diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 3f76a40..f9f74ec 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -1589,9 +1589,14 @@ ExecutePlan(EState *estate,
 	 * If a tuple count was supplied, we must force the plan to run without
 	 * parallelism, because we might exit early.  Also disable parallelism
 	 * when writing into a relation, because no database changes are allowed
-	 * in parallel mode.
+	 * in parallel mode. For SQL or other PL functions, the supplied tuple
+	 * count is always one, To enable parallelism for queries coming from SQL
+	 * or other PL functions, we enable parallelism if the planner considers
+	 * it safe.
 	 */
-	if (numberTuples || dest->mydest == DestIntoRel)
+
+	if (dest->mydest == DestIntoRel || numberTuples &&
+		(dest->mydest != DestSPI && dest->mydest != DestSQLFunction))
 		use_parallel_mode = false;
 
 	if (use_parallel_mode)
@@ -1662,7 +1667,16 @@ ExecutePlan(EState *estate,
 		 */
 		current_tuple_count++;
 		if (numberTuples && numberTuples == current_tuple_count)
+		{
+			/*
+			 * For the queries coming from SQL or PL functions, this condition
+			 * will be satisfied for the first tuple and since we enabled
+			 * parallel workers for it, a proper shutdown of the workers would
+			 * be required.
+			 */
+			(void) ExecShutdownNode(planstate);
 			break;
+		}
 	}
 
 	if (use_parallel_mode)
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
index 55f97b1..03f6771 100644
--- a/src/backend/executor/spi.c
+++ b/src/backend/executor/spi.c
@@ -314,7 +314,12 @@ SPI_execute(const char *src, bool read_only, long tcount)
 
 	memset(&plan, 0, sizeof(_SPI_plan));
 	plan.magic = _SPI_PLAN_MAGIC;
-	plan.cursor_options = 0;
+
+	/* Allow parallelism if the query is read-only */
+	if (read_only)
+		plan.cursor_options = CURSOR_OPT_PARALLEL_OK;
+	else
+		plan.cursor_options = 0;
 
 	_SPI_prepare_oneshot_plan(src, &plan);
 
@@ -458,7 +463,12 @@ SPI_execute_with_args(const char *src,
 
 	memset(&plan, 0, sizeof(_SPI_plan));
 	plan.magic = _SPI_PLAN_MAGIC;
-	plan.cursor_options = 0;
+
+	/* Allow parallelism if the query is read-only */
+	if (read_only)
+		plan.cursor_options = CURSOR_OPT_PARALLEL_OK;
+	else
+		plan.cursor_options = 0;
 	plan.nargs = nargs;
 	plan.argtypes = argtypes;
 	plan.parserSetup = NULL;
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index 6fc3db0..b4f462f 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -3625,7 +3625,12 @@ exec_stmt_execsql(PLpgSQL_execstate *estate,
 	{
 		ListCell   *l;
 
-		exec_prepare_plan(estate, expr, 0);
+		/* Allow parallelism if the function is not trigger type. */
+		if (estate->func->fn_is_trigger == PLPGSQL_NOT_TRIGGER)
+			exec_prepare_plan(estate, expr, CURSOR_OPT_PARALLEL_OK);
+		else
+			exec_prepare_plan(estate, expr, 0);
+
 		stmt->mod_stmt = false;
 		foreach(l, SPI_plan_get_plan_sources(expr->plan))
 		{
@@ -5172,7 +5177,13 @@ exec_eval_expr(PLpgSQL_execstate *estate,
 	 * If first time through, create a plan for this expression.
 	 */
 	if (expr->plan == NULL)
-		exec_prepare_plan(estate, expr, 0);
+	{
+		/* Allow parallelism is the function is not trigger type. */
+		if (estate->func->fn_is_trigger == PLPGSQL_NOT_TRIGGER)
+			exec_prepare_plan(estate, expr, CURSOR_OPT_PARALLEL_OK);
+		else
+			exec_prepare_plan(estate, expr, 0);
+	}
 
 	/*
 	 * If this is a simple expression, bypass SPI and use the executor
@@ -5183,9 +5194,14 @@ exec_eval_expr(PLpgSQL_execstate *estate,
 		return result;
 
 	/*
-	 * Else do it the hard way via exec_run_select
+	 * Else do it the hard way via exec_run_select. Enable parallelism if
+	 * function is not trigger type.
 	 */
-	rc = exec_run_select(estate, expr, 2, NULL, false);
+	if (estate->func->fn_is_trigger == PLPGSQL_NOT_TRIGGER)
+		rc = exec_run_select(estate, expr, 2, NULL, true);
+	else
+		rc = exec_run_select(estate, expr, 2, NULL, false);
+
 	if (rc != SPI_OK_SELECT)
 		ereport(ERROR,
 				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
