diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index de77f14573..462f27fc04 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -3858,7 +3858,8 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"'  # Windows
         This parameter specifies the time stamp up to which recovery
         will proceed.
         The precise stopping point is also influenced by
-        <xref linkend="guc-recovery-target-inclusive"/>.
+        <xref linkend="guc-recovery-target-inclusive"/> and
+        <xref linkend="guc-recovery-target-use-origin-time"/>.
        </para>
 
        <para>
@@ -3939,6 +3940,27 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"'  # Windows
       </listitem>
      </varlistentry>
 
+     <varlistentry id="guc-recovery-target-use-origin-time"
+                   xreflabel="recovery_target_use_origin_time">
+      <term><varname>recovery_target_use_origin_time</varname> (<type>boolean</type>)
+      <indexterm>
+        <primary><varname>recovery_target_use_origin_time</varname> configuration parameter</primary>
+      </indexterm>
+      </term>
+      <listitem>
+       <para>
+        Specifies whether to use the timestamp from the local commit
+        record (<literal>off</literal>), or, if one exists, to use
+        the timestamp as recorded by the origin, for commits that
+        arrive by logical replication from another server.
+        This allows a PITR recovery to have a single consistent
+        timestamp across multiple servers, if that is desirable.
+        Applies when <xref linkend="guc-recovery-target-time"/>
+        is specified.  Default is <literal>on</literal>.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry id="guc-recovery-target-timeline"
                    xreflabel="recovery_target_timeline">
       <term><varname>recovery_target_timeline</varname> (<type>string</type>)
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 0a0771a18e..9c0c5e389c 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -275,6 +275,7 @@ char	   *recoveryEndCommand = NULL;
 char	   *archiveCleanupCommand = NULL;
 RecoveryTargetType recoveryTarget = RECOVERY_TARGET_UNSET;
 bool		recoveryTargetInclusive = true;
+bool		recoveryTargetUseOriginTime = false;
 int			recoveryTargetAction = RECOVERY_TARGET_ACTION_PAUSE;
 TransactionId recoveryTargetXid;
 char	   *recovery_target_time_string;
@@ -5840,25 +5841,81 @@ static bool
 getRecordTimestamp(XLogReaderState *record, TimestampTz *recordXtime)
 {
 	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
-	uint8		xact_info = info & XLOG_XACT_OPMASK;
 	uint8		rmid = XLogRecGetRmid(record);
 
-	if (rmid == RM_XLOG_ID && info == XLOG_RESTORE_POINT)
+	if (rmid == RM_XLOG_ID)
 	{
-		*recordXtime = ((xl_restore_point *) XLogRecGetData(record))->rp_time;
-		return true;
-	}
-	if (rmid == RM_XACT_ID && (xact_info == XLOG_XACT_COMMIT ||
-							   xact_info == XLOG_XACT_COMMIT_PREPARED))
-	{
-		*recordXtime = ((xl_xact_commit *) XLogRecGetData(record))->xact_time;
-		return true;
+		if (info == XLOG_RESTORE_POINT)
+		{
+			*recordXtime = ((xl_restore_point *) XLogRecGetData(record))->rp_time;
+			return true;
+		}
+		if (info == XLOG_CHECKPOINT_ONLINE ||
+			info == XLOG_CHECKPOINT_SHUTDOWN)
+		{
+			*recordXtime = time_t_to_timestamptz(((CheckPoint *) XLogRecGetData(record))->time);
+			return true;
+		}
+		if (info == XLOG_END_OF_RECOVERY)
+		{
+			*recordXtime = ((xl_end_of_recovery *) XLogRecGetData(record))->end_time;
+			return true;
+		}
 	}
-	if (rmid == RM_XACT_ID && (xact_info == XLOG_XACT_ABORT ||
-							   xact_info == XLOG_XACT_ABORT_PREPARED))
+	if (rmid == RM_XACT_ID)
 	{
-		*recordXtime = ((xl_xact_abort *) XLogRecGetData(record))->xact_time;
-		return true;
+		uint8		xact_info = info & XLOG_XACT_OPMASK;
+
+		if (xact_info == XLOG_XACT_COMMIT ||
+			xact_info == XLOG_XACT_COMMIT_PREPARED)
+		{
+			if (recoveryTargetUseOriginTime)
+			{
+				xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
+				xl_xact_parsed_commit parsed;
+
+				ParseCommitRecord(XLogRecGetInfo(record),
+								  xlrec,
+								  &parsed);
+				*recordXtime = parsed.origin_timestamp;
+			}
+			else
+				*recordXtime = ((xl_xact_commit *) XLogRecGetData(record))->xact_time;
+			return true;
+		}
+		if (xact_info == XLOG_XACT_ABORT ||
+			xact_info == XLOG_XACT_ABORT_PREPARED)
+		{
+			if (recoveryTargetUseOriginTime)
+			{
+				xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
+				xl_xact_parsed_abort parsed;
+
+				ParseAbortRecord(XLogRecGetInfo(record),
+								  xlrec,
+								  &parsed);
+				*recordXtime = parsed.origin_timestamp;
+			}
+			else
+				*recordXtime = ((xl_xact_abort *) XLogRecGetData(record))->xact_time;
+			return true;
+		}
+		if (xact_info == XLOG_XACT_PREPARE)
+		{
+			if (recoveryTargetUseOriginTime)
+			{
+				xl_xact_prepare *xlrec = (xl_xact_prepare *) XLogRecGetData(record);
+				xl_xact_parsed_prepare parsed;
+
+				ParsePrepareRecord(XLogRecGetInfo(record),
+								  xlrec,
+								  &parsed);
+				*recordXtime = parsed.origin_timestamp;
+			}
+			else
+				*recordXtime = ((xl_xact_prepare *) XLogRecGetData(record))->prepared_at;
+			return true;
+		}
 	}
 	return false;
 }
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index e91d5a3cfd..9693afc602 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -1906,6 +1906,16 @@ static struct config_bool ConfigureNamesBool[] =
 		NULL, NULL, NULL
 	},
 
+	{
+		{"recovery_target_use_origin_time", PGC_POSTMASTER, WAL_RECOVERY_TARGET,
+			gettext_noop("Sets whether to use local or origin transaction time with recovery target."),
+			NULL
+		},
+		&recoveryTargetUseOriginTime,
+		false,
+		NULL, NULL, NULL
+	},
+
 	{
 		{"hot_standby", PGC_POSTMASTER, REPLICATION_STANDBY,
 			gettext_noop("Allows connections and queries during recovery."),
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index c0a560204b..65c6633c0d 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -84,6 +84,7 @@ extern char *recoveryRestoreCommand;
 extern char *recoveryEndCommand;
 extern char *archiveCleanupCommand;
 extern bool recoveryTargetInclusive;
+extern bool recoveryTargetUseOriginTime;
 extern int	recoveryTargetAction;
 extern int	recovery_min_apply_delay;
 extern char *PrimaryConnInfo;
