diff --git a/doc/src/sgml/recovery-config.sgml b/doc/src/sgml/recovery-config.sgml
index 8c24ae2..59ef116 100644
--- a/doc/src/sgml/recovery-config.sgml
+++ b/doc/src/sgml/recovery-config.sgml
@@ -211,6 +211,11 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"'  # Windows
         The precise stopping point is also influenced by
         <xref linkend="recovery-target-inclusive">.
        </para>
+       <para>
+        This parameter also checks if the checkpoint time of the backup being used is earlier than the specified recovery_target_time. 
+        In other words, the recovery will not proceed further if the checkpoint time of the backup is later than the specified recovery_target_time.
+       </para>
+
       </listitem>
      </varlistentry>
 
@@ -231,6 +236,11 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"'  # Windows
         The precise stopping point is also influenced by
         <xref linkend="recovery-target-inclusive">.
        </para>
+       <para>
+        This parameter also checks if the latest completed xid of the backup is earlier than the specified recovery target xid.
+        In other words, the recovery will not proceed further if the latest completed xid of the backup is later than the specified target xid.
+       </para>
+
       </listitem>
      </varlistentry>
 
@@ -248,6 +258,11 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"'  # Windows
         parameter is parsed using the system data type
         <link linkend="datatype-pg-lsn"><type>pg_lsn</></link>.
        </para>
+       <para>
+        This parameter also checks if the current checkpoint's redo position of the backup is earlier than the specified recovery target lsn.
+        In other words, the recovery will not proceed further if the latest checkpoint's redo position of the backup is later than the specified target lsn.
+       </para>
+
       </listitem>
      </varlistentry>
      </variablelist>
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 8379133..3043864 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -826,6 +826,7 @@ static MemoryContext walDebugCxt = NULL;
 #endif
 
 static void readRecoveryCommandFile(void);
+static void recoveryStartsHere(void);
 static void exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog);
 static bool recoveryStopsBefore(XLogReaderState *record);
 static bool recoveryStopsAfter(XLogReaderState *record);
@@ -5449,6 +5450,67 @@ getRecordTimestamp(XLogReaderState *record, TimestampTz *recordXtime)
 	return false;
 }
 
+/* When performing point-in-time-recovery, this function identifies if
+ * the specified recovery target (recovery_target_time, recovery_target_lsn and recovery_target_xid) is prior to that of the backup.
+ * Which means, recovery cannot proceed if the recovery target point is prior to backup start point.
+ */
+
+static void
+recoveryStartsHere(void)
+{
+	/*
+	 * Check if the recovery target xid is older than the latest completed xid
+	 * of the backup
+	 */
+
+	if (recoveryTarget == RECOVERY_TARGET_XID)
+	{
+		if (TransactionIdPrecedes(recoveryTargetXid,
+							 ControlFile->checkPointCopy.latestCompletedXid))
+		{
+			ereport(ERROR,
+					(errmsg("recovery_target_xid %u is older than the latest Completed Xid %u", recoveryTargetXid, ControlFile->checkPointCopy.latestCompletedXid),
+					 errhint("This means that the backup being used is much later than the recovery target position.\n"
+							 "You might need to use a backup taken prior to the recovery target point.")));
+		}
+	}
+
+	/*
+	 * Check if the recovery target lsn is prior to the latest checkpointi's
+	 * redo position of the backup
+	 */
+
+	if (recoveryTarget == RECOVERY_TARGET_LSN)
+	{
+		if (recoveryTargetLSN < ControlFile->checkPointCopy.redo)
+		{
+			ereport(ERROR,
+					(errmsg("recovery_target_lsn \"%X/%X\" is older than the backup start LSN \"%X/%X\"",
+							(uint32) (recoveryTargetLSN >> 32),
+							(uint32) recoveryTargetLSN, (uint32) (ControlFile->checkPointCopy.redo >> 32), (uint32) ControlFile->checkPointCopy.redo),
+					 errhint("This means that the backup being used is much later than the recovery target position.\n"
+							 "You might need to use a backup taken prior to the recovery target point.")));
+		}
+	}
+
+	/*
+	 * Check if the recovery target time is prior to the current timestamp of
+	 * the backup
+	 */
+
+	if (recoveryTarget == RECOVERY_TARGET_TIME)
+	{
+		if (recoveryTargetTime < ControlFile->checkPointCopy.time)
+		{
+			ereport(ERROR,
+					(errmsg("recovery_target_time %s is older than the backup start time %s", timestamptz_to_str(recoveryTargetTime),
+					   timestamptz_to_str(ControlFile->checkPointCopy.time)),
+					 errhint("This means that the backup being used is much later than the recovery target position.\n"
+							 "You might need to use a backup taken prior to the recovery target point.")));
+		}
+	}
+}
+
 /*
  * For point-in-time recovery, this function decides whether we want to
  * stop applying the XLOG before the current record.
@@ -6182,6 +6244,9 @@ StartupXLOG(void)
 					(errmsg("starting archive recovery")));
 	}
 
+	/* Check if archive recovery can start at all */
+	recoveryStartsHere();
+
 	/*
 	 * Take ownership of the wakeup latch if we're going to sleep during
 	 * recovery.
@@ -8531,6 +8596,7 @@ CreateCheckPoint(int flags)
 	checkPoint.nextXid = ShmemVariableCache->nextXid;
 	checkPoint.oldestXid = ShmemVariableCache->oldestXid;
 	checkPoint.oldestXidDB = ShmemVariableCache->oldestXidDB;
+	checkPoint.latestCompletedXid = ShmemVariableCache->latestCompletedXid;
 	LWLockRelease(XidGenLock);
 
 	LWLockAcquire(CommitTsLock, LW_SHARED);
diff --git a/src/bin/pg_controldata/pg_controldata.c b/src/bin/pg_controldata/pg_controldata.c
index 20077a6..f340f1c 100644
--- a/src/bin/pg_controldata/pg_controldata.c
+++ b/src/bin/pg_controldata/pg_controldata.c
@@ -222,6 +222,8 @@ main(int argc, char *argv[])
 	printf(_("Latest checkpoint's NextXID:          %u:%u\n"),
 		   ControlFile->checkPointCopy.nextXidEpoch,
 		   ControlFile->checkPointCopy.nextXid);
+	printf(_("Latest checkpoint's latestCompletedXID: %u\n"),
+		   ControlFile->checkPointCopy.latestCompletedXid);
 	printf(_("Latest checkpoint's NextOID:          %u\n"),
 		   ControlFile->checkPointCopy.nextOid);
 	printf(_("Latest checkpoint's NextMultiXactId:  %u\n"),
diff --git a/src/include/catalog/pg_control.h b/src/include/catalog/pg_control.h
index 23731e9..7ed9484 100644
--- a/src/include/catalog/pg_control.h
+++ b/src/include/catalog/pg_control.h
@@ -21,7 +21,7 @@
 
 
 /* Version identifier for this pg_control format */
-#define PG_CONTROL_VERSION	960
+#define PG_CONTROL_VERSION	100
 
 /*
  * Body of CheckPoint XLOG records.  This is declared here because we keep
@@ -58,6 +58,7 @@ typedef struct CheckPoint
 	 * set to InvalidTransactionId.
 	 */
 	TransactionId oldestActiveXid;
+	TransactionId latestCompletedXid;
 } CheckPoint;
 
 /* XLOG info values for XLOG rmgr */
