diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64LibConstructor.c b/ArmPkg/Library/ArmLib/AArch64/AArch64BaseLibConstructor.c
similarity index 100%
rename from ArmPkg/Library/ArmLib/AArch64/AArch64LibConstructor.c
rename to ArmPkg/Library/ArmLib/AArch64/AArch64BaseLibConstructor.c
diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf
index 58684e8492f2..ef9d261b910d 100644
--- a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf
+++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf
@@ -32,7 +32,7 @@ [Sources.AARCH64]
 
   ../Common/AArch64/ArmLibSupport.S
   ../Common/ArmLib.c
-  AArch64LibConstructor.c
+  AArch64BaseLibConstructor.c
 
 [Packages]
   ArmPkg/ArmPkg.dec
diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64LibPei.inf b/ArmPkg/Library/ArmLib/AArch64/AArch64LibPei.inf
new file mode 100644
index 000000000000..96517f5c167d
--- /dev/null
+++ b/ArmPkg/Library/ArmLib/AArch64/AArch64LibPei.inf
@@ -0,0 +1,43 @@
+#/** @file
+#
+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+# Portions copyright (c) 2011 - 2014, ARM Limited. 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                      = AArch64Lib
+  FILE_GUID                      = ef20ddf5-b334-47b3-94cf-52ff44c29138
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = ArmLib|PEIM
+  CONSTRUCTOR                    = AArch64LibConstructor
+
+[Sources.AARCH64]
+  AArch64Lib.c
+  AArch64Mmu.c
+  AArch64ArchTimer.c
+  ArmLibSupportV8.S
+  AArch64Support.S
+  AArch64ArchTimerSupport.S
+
+  ../Common/AArch64/ArmLibSupport.S
+  ../Common/ArmLib.c
+  AArch64PeiLibConstructor.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  MemoryAllocationLib
+  CacheMaintenanceLib
diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64PeiLibConstructor.c b/ArmPkg/Library/ArmLib/AArch64/AArch64PeiLibConstructor.c
new file mode 100644
index 000000000000..db93212b3f05
--- /dev/null
+++ b/ArmPkg/Library/ArmLib/AArch64/AArch64PeiLibConstructor.c
@@ -0,0 +1,57 @@
+#/* @file
+#
+#  Copyright (c) 2016, Linaro Limited. 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 <Base.h>
+
+#include <Library/ArmLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/DebugLib.h>
+
+EFI_STATUS
+EFIAPI
+AArch64LibConstructor (
+  IN       EFI_PEI_FILE_HANDLE       FileHandle,
+  IN CONST EFI_PEI_SERVICES          **PeiServices
+  )
+{
+  extern UINT32             ArmReplaceLiveTranslationEntrySize;
+
+  EFI_FV_FILE_INFO          FileInfo;
+  EFI_STATUS                Status;
+
+  Status = (*PeiServices)->FfsGetFileInfo (FileHandle, &FileInfo);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Some platforms do not cope very well with cache maintenance being
+  // performed on regions backed by NOR flash. Since the cache maintenance
+  // is unnecessary to begin with in that case, perform it only when not
+  // executing in place.
+  //
+  if ((UINTN)FileInfo.Buffer <= (UINTN)ArmReplaceLiveTranslationEntry &&
+      ((UINTN)FileInfo.Buffer + FileInfo.BufferSize >=
+       (UINTN)ArmReplaceLiveTranslationEntry + ArmReplaceLiveTranslationEntrySize)) {
+    DEBUG ((EFI_D_INFO, "ArmLib: skipping cache maintence on XIP PEIM\n"));
+  } else {
+    DEBUG ((EFI_D_INFO, "ArmLib: performing cache maintence on shadowed PEIM\n"));
+    //
+    // The ArmReplaceLiveTranslationEntry () helper function may be invoked
+    // with the MMU off so we have to ensure that it gets cleaned to the PoC
+    //
+    WriteBackDataCacheRange (ArmReplaceLiveTranslationEntry,
+      ArmReplaceLiveTranslationEntrySize);
+  }
+
+  return RETURN_SUCCESS;
+}
