diff --git a/src/backend/replication/logical/tablesync.c b/src/backend/replication/logical/tablesync.c
index c56d42dcd2..6874e8c2ce 100644
--- a/src/backend/replication/logical/tablesync.c
+++ b/src/backend/replication/logical/tablesync.c
@@ -120,6 +120,7 @@
 #include "utils/rls.h"
 #include "utils/snapmgr.h"
 #include "utils/syscache.h"
+#include "utils/usercontext.h"
 
 static bool table_states_valid = false;
 static List *table_states_not_ready = NIL;
@@ -1253,6 +1254,8 @@ LogicalRepSyncTableStart(XLogRecPtr *origin_startpos)
 	char		originname[NAMEDATALEN];
 	RepOriginId originid;
 	bool		must_use_password;
+	UserContext	ucxt;
+	bool		run_as_owner;
 
 	/* Check the state of the table synchronization. */
 	StartTransactionCommand();
@@ -1374,6 +1377,15 @@ LogicalRepSyncTableStart(XLogRecPtr *origin_startpos)
 	 */
 	rel = table_open(MyLogicalRepWorker->relid, RowExclusiveLock);
 
+	/*
+	 * Make sure that the copy command runs as the table owner, unless
+	 * the user has opted out of that behaviour.
+	 */
+	run_as_owner = MySubscription->runasowner;
+
+	if (!run_as_owner)
+		SwitchToUntrustedUser(rel->rd_rel->relowner, &ucxt);
+
 	/*
 	 * Check that our table sync worker has permission to insert into the
 	 * target table.
@@ -1469,6 +1481,9 @@ LogicalRepSyncTableStart(XLogRecPtr *origin_startpos)
 						res->err)));
 	walrcv_clear_result(res);
 
+	if(!run_as_owner)
+		RestoreUserContext(&ucxt);
+
 	table_close(rel, NoLock);
 
 	/* Make the copy visible. */
diff --git a/src/test/subscription/t/033_run_as_table_owner.pl b/src/test/subscription/t/033_run_as_table_owner.pl
index 0aa8a093ef..6d4051072c 100644
--- a/src/test/subscription/t/033_run_as_table_owner.pl
+++ b/src/test/subscription/t/033_run_as_table_owner.pl
@@ -70,8 +70,8 @@ sub revoke_superuser
 
 # Create publisher and subscriber nodes with schemas owned and published by
 # "regress_alice" but subscribed and replicated by different role
-# "regress_admin".  For partitioned tables, layout the partitions differently
-# on the publisher than on the subscriber.
+# "regress_admin" and "regress_admin2". For partitioned tables, layout the
+# partitions differently on the publisher than on the subscriber.
 #
 $node_publisher = PostgreSQL::Test::Cluster->new('publisher');
 $node_subscriber = PostgreSQL::Test::Cluster->new('subscriber');
@@ -86,15 +86,18 @@ for my $node ($node_publisher, $node_subscriber)
 	$node->safe_psql(
 		'postgres', qq(
   CREATE ROLE regress_admin SUPERUSER LOGIN;
+  CREATE ROLE regress_admin2 SUPERUSER LOGIN;
   CREATE ROLE regress_alice NOSUPERUSER LOGIN;
   GRANT CREATE ON DATABASE postgres TO regress_alice;
   SET SESSION AUTHORIZATION regress_alice;
   CREATE SCHEMA alice;
   GRANT USAGE ON SCHEMA alice TO regress_admin;
+  GRANT USAGE ON SCHEMA alice TO regress_admin2;
 
   CREATE TABLE alice.unpartitioned (i INTEGER);
   ALTER TABLE alice.unpartitioned REPLICA IDENTITY FULL;
   GRANT SELECT ON TABLE alice.unpartitioned TO regress_admin;
+  GRANT SELECT ON TABLE alice.unpartitioned TO regress_admin2;
   ));
 }
 $node_publisher->safe_psql(
@@ -192,4 +195,37 @@ GRANT regress_alice TO regress_admin WITH INHERIT TRUE, SET FALSE;
 expect_replication("alice.unpartitioned", 3, 7, 13,
 	"with INHERIT but not SET ROLE can replicate");
 
+# Remove the subscrition and truncate the table for the initial data sync
+# tests.
+$node_subscriber->safe_psql(
+	    'postgres', qq(
+DROP SUBSCRIPTION admin_sub;
+TRUNCATE alice.unpartitioned;
+));
+
+# Create a new subscription "admin_sub" owned by regress_admin2. It's
+# disabled so that we revoke superuser privilege after creation.
+$node_subscriber->safe_psql(
+    'postgres', qq(
+SET SESSION AUTHORIZATION regress_admin2;
+CREATE SUBSCRIPTION admin_sub CONNECTION '$publisher_connstr' PUBLICATION alice
+WITH (run_as_owner = false, password_required = false, copy_data = true, enabled = false);
+));
+
+# Revoke superuser privilege for "regress_admin2", and give it the
+# ability to SET ROLE. Then enable the subscription "admin_sub".
+revoke_superuser("regress_admin2");
+$node_subscriber->safe_psql(
+    'postgres', qq(
+GRANT regress_alice TO regress_admin2 WITH INHERIT FALSE, SET TRUE;
+ALTER SUBSCRIPTION admin_sub ENABLE;
+));
+
+# Because the initial data sync is working as the table owner, all
+# dat should be copied.
+$node_subscriber->wait_for_subscription_sync($node_publisher,
+					     'admin_sub');
+expect_replication("alice.unpartitioned", 3, 7, 13,
+		   "table owner can do the initial data copy");
+
 done_testing();
