diff --git a/MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf b/MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf
index 385eec9ed4..7021e54274 100644
--- a/MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf
+++ b/MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf
@@ -7,6 +7,9 @@
 #  used by SMM drivers and runtime drivers, ACPI timer is recommended for SMM
 #  drivers and runtime drivers.
 #
+# Note that for IA-32 and x64, this library only supports xAPIC mode. If x2APIC
+# support is desired, the SecPeiDxeTimerLibUefiCpu library can be used.
+#
 # Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
 #
 #  This program and the accompanying materials
diff --git a/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.inf b/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.inf
new file mode 100644
index 0000000000..bf76f35fa3
--- /dev/null
+++ b/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.inf
@@ -0,0 +1,63 @@
+## @file
+# Instance of Timer Library only using CPU resources.
+#
+# Timer Library that only uses CPU resources to provide calibrated delays
+#  on IA-32, x64, and IPF.
+# Note: Because CPU Local APIC and ITC could be programmed by OS, it cannot be
+#  used by SMM drivers and runtime drivers, ACPI timer is recommended for SMM
+#  drivers and runtime drivers.
+#
+# This library differs with the SecPeiDxeTimerLibCpu library in the MdePkg in
+# that it uses the local APIC library so that it supports x2APIC mode.
+#
+# Copyright (c) 2010, Intel Corporation. All rights reserved.
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php.
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SecPeiDxeTimerLibUefiCpu
+  FILE_GUID                      = 4FFF2014-2086-4ee6-9B58-886D1967861C
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = TimerLib|BASE DXE_CORE DXE_DRIVER DXE_SAL_DRIVER PEIM PEI_CORE SEC UEFI_APPLICATION UEFI_DRIVER
+
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF
+#
+
+[Sources.Ia32, Sources.X64]
+  X86TimerLib.c
+
+[Sources.IPF]
+  IpfTimerLib.c
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+  BaseLib
+
+[LibraryClasses.IA32, LibraryClasses.X64]
+  PcdLib
+  DebugLib
+  LocalApicLib
+
+[LibraryClasses.IPF]
+  PalLib
+
+
+[Pcd.IA32, Pcd.X64]
+  gEfiMdePkgTokenSpaceGuid.PcdFSBClock  ## CONSUMES
+
diff --git a/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/X86TimerLib.c b/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/X86TimerLib.c
new file mode 100644
index 0000000000..3ca3ca8008
--- /dev/null
+++ b/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/X86TimerLib.c
@@ -0,0 +1,195 @@
+/** @file
+  Timer Library functions built upon local APIC on IA32/x64.
+
+  This library uses the local APIC library so that it supports x2APIC mode.
+  
+  Copyright (c) 2010, Intel Corporation. All rights reserved.
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php.
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+  Internal function to return the frequency of the local APIC timer.
+
+  @return The frequency of the timer in Hz.
+
+**/
+UINT32
+EFIAPI
+InternalX86GetTimerFrequency (
+  VOID
+  )
+{
+  UINTN Divisor;
+
+  GetApicTimerState (&Divisor, NULL, NULL);
+  return PcdGet32(PcdFSBClock) / (UINT32)Divisor;
+}
+
+/**
+  Stalls the CPU for at least the given number of ticks.
+
+  Stalls the CPU for at least the given number of ticks. It's invoked by
+  MicroSecondDelay() and NanoSecondDelay().
+
+  @param  Delay     A period of time to delay in ticks.
+
+**/
+VOID
+EFIAPI
+InternalX86Delay (
+  IN      UINT32                    Delay
+  )
+{
+  INT32                             Ticks;
+  UINT32                            PowerOfTwoCounter;
+
+  //
+  // The target timer count is calculated here
+  //
+  Ticks = GetApicTimerCurrentCount () - Delay;
+
+  //
+  // Wait until time out
+  // Delay > 2^31 could not be handled by this function
+  // Timer wrap-arounds are handled correctly by this function
+  //
+  PowerOfTwoCounter = GetPowerOfTwo32 (GetApicTimerInitCount ());
+  while (((UINT32)(GetApicTimerCurrentCount () - Ticks) & PowerOfTwoCounter) == 0) {
+    CpuPause ();
+  }
+}
+
+/**
+  Stalls the CPU for at least the given number of microseconds.
+
+  Stalls the CPU for the number of microseconds specified by MicroSeconds.
+
+  @param  MicroSeconds  The minimum number of microseconds to delay.
+
+  @return The value of MicroSeconds inputted.
+
+**/
+UINTN
+EFIAPI
+MicroSecondDelay (
+  IN      UINTN                     MicroSeconds
+  )
+{
+  InternalX86Delay (
+    (UINT32)DivU64x32 (
+              MultU64x64 (
+                InternalX86GetTimerFrequency (),
+                MicroSeconds
+                ),
+              1000000u
+              )
+    );
+  return MicroSeconds;
+}
+
+/**
+  Stalls the CPU for at least the given number of nanoseconds.
+
+  Stalls the CPU for the number of nanoseconds specified by NanoSeconds.
+
+  @param  NanoSeconds The minimum number of nanoseconds to delay.
+
+  @return The value of NanoSeconds inputted.
+
+**/
+UINTN
+EFIAPI
+NanoSecondDelay (
+  IN      UINTN                     NanoSeconds
+  )
+{
+  InternalX86Delay (
+    (UINT32)DivU64x32 (
+              MultU64x64 (
+                InternalX86GetTimerFrequency (),
+                NanoSeconds
+                ),
+              1000000000u
+              )
+    );
+  return NanoSeconds;
+}
+
+/**
+  Retrieves the current value of a 64-bit free running performance counter.
+
+  The counter can either count up by 1 or count down by 1. If the physical
+  performance counter counts by a larger increment, then the counter values
+  must be translated. The properties of the counter can be retrieved from
+  GetPerformanceCounterProperties().
+
+  @return The current value of the free running performance counter.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounter (
+  VOID
+  )
+{
+  return (UINT64)GetApicTimerCurrentCount ();
+}
+
+/**
+  Retrieves the 64-bit frequency in Hz and the range of performance counter
+  values.
+
+  If StartValue is not NULL, then the value that the performance counter starts
+  with immediately after is it rolls over is returned in StartValue. If
+  EndValue is not NULL, then the value that the performance counter end with
+  immediately before it rolls over is returned in EndValue. The 64-bit
+  frequency of the performance counter in Hz is always returned. If StartValue
+  is less than EndValue, then the performance counter counts up. If StartValue
+  is greater than EndValue, then the performance counter counts down. For
+  example, a 64-bit free running counter that counts up would have a StartValue
+  of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter
+  that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.
+
+  @param  StartValue  The value the performance counter starts with when it
+                      rolls over.
+  @param  EndValue    The value that the performance counter ends with before
+                      it rolls over.
+
+  @return The frequency in Hz.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounterProperties (
+  OUT      UINT64                    *StartValue,  OPTIONAL
+  OUT      UINT64                    *EndValue     OPTIONAL
+  )
+{
+  if (StartValue != NULL) {
+    *StartValue = (UINT64)GetApicTimerInitCount ();
+    //
+    // make sure StartValue is all 1s from High Bit
+    //
+    ASSERT ((*StartValue & (*StartValue + 1)) == 0);
+  }
+
+  if (EndValue != NULL) {
+    *EndValue = 0;
+  }
+
+  return (UINT64) InternalX86GetTimerFrequency ();
+}
diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
index c414ae8b29..12207f6030 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -68,6 +68,7 @@
 [Components]
   UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
   UefiCpuPkg/CpuIoPei/CpuIoPei.inf
+  UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.inf
 
 [Components.IA32, Components.X64]
   UefiCpuPkg/CpuDxe/CpuDxe.inf