diff --git a/MdeModulePkg/Universal/CapsuleRuntimeDxe/Arm/CapsuleReset.c b/MdeModulePkg/Universal/CapsuleRuntimeDxe/Arm/CapsuleReset.c
new file mode 100644
index 000000000000..7e0ca06ce7d0
--- /dev/null
+++ b/MdeModulePkg/Universal/CapsuleRuntimeDxe/Arm/CapsuleReset.c
@@ -0,0 +1,77 @@
+ /** @file
+  ARM implementation of architecture specific routines related to
+  PersistAcrossReset capsules
+
+  Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
+
+  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 "CapsuleService.h"
+
+#include <Library/CacheMaintenanceLib.h>
+
+/**
+  Whether the platform supports capsules that persist across reset. Note that
+  some platforms only support such capsules at boot time.
+
+  @return TRUE  if a PersistAcrossReset capsule may be passed to UpdateCapsule()
+                at this time
+          FALSE otherwise
+**/
+BOOLEAN
+EFIAPI
+IsPersistAcrossResetCapsuleSupported (
+  VOID
+  )
+{
+  //
+  // ARM requires the capsule payload to be cleaned to the point of coherency
+  // (PoC), but only permits doing so using cache maintenance instructions that
+  // operate on virtual addresses. Since at runtime, we don't know the virtual
+  // addresses of the data structures that make up the scatter/gather list, we
+  // cannot perform the maintenance, and all we can do is give up.
+  //
+  return FeaturePcdGet (PcdSupportUpdateCapsuleReset) && !EfiAtRuntime ();
+}
+
+/**
+  Writes Back a range of data cache lines covering a set of capsules in memory.
+
+  Writes Back the data cache lines specified by ScatterGatherList.
+
+  @param  ScatterGatherList Physical address of the data structure that
+                            describes a set of capsules in memory
+
+**/
+VOID
+EFIAPI
+CapsuleCacheWriteBack (
+  IN  EFI_PHYSICAL_ADDRESS    ScatterGatherList
+  )
+{
+  EFI_CAPSULE_BLOCK_DESCRIPTOR    *Desc;
+
+  Desc = (EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)ScatterGatherList;
+  do {
+    WriteBackDataCacheRange (Desc, sizeof *Desc);
+
+    if (Desc->Length > 0) {
+      WriteBackDataCacheRange ((VOID *)(UINTN)Desc->Union.DataBlock,
+                               Desc->Length
+                               );
+      Desc++;
+    } else if (Desc->Union.ContinuationPointer > 0) {
+      Desc = (EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)Desc->Union.ContinuationPointer;
+    }
+  } while (Desc->Length > 0 || Desc->Union.ContinuationPointer > 0);
+
+  WriteBackDataCacheRange (Desc, sizeof *Desc);
+}
diff --git a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleReset.c b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleReset.c
new file mode 100644
index 000000000000..09616999e3f8
--- /dev/null
+++ b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleReset.c
@@ -0,0 +1,51 @@
+/** @file
+  Default implementation of architecture specific routines related to
+  PersistAcrossReset capsules
+
+  Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
+
+  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 "CapsuleService.h"
+
+/**
+  Whether the platform supports capsules that persist across reset. Note that
+  some platforms only support such capsules at boot time.
+
+  @return TRUE  if a PersistAcrossReset capsule may be passed to UpdateCapsule()
+                at this time
+          FALSE otherwise
+**/
+BOOLEAN
+EFIAPI
+IsPersistAcrossResetCapsuleSupported (
+  VOID
+  )
+{
+  return FeaturePcdGet (PcdSupportUpdateCapsuleReset);
+}
+
+/**
+  Writes Back a range of data cache lines covering a set of capsules in memory.
+
+  Writes Back the data cache lines specified by ScatterGatherList.
+
+  @param  ScatterGatherList Physical address of the data structure that
+                            describes a set of capsules in memory
+
+**/
+VOID
+EFIAPI
+CapsuleCacheWriteBack (
+  IN  EFI_PHYSICAL_ADDRESS    ScatterGatherList
+  )
+{
+}
diff --git a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
index 9ab04ce1b301..43a29ee22948 100644
--- a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+++ b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
@@ -27,17 +27,24 @@ [Defines]
 #
 # The following information is for reference only and not required by the build tools.
 #
-#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC ARM AARCH64
 #
 
 [Sources]
   CapsuleService.c
+  CapsuleService.h
 
-[Sources.Ia32, Sources.IPF, Sources.EBC, Sources.ARM, Sources.AARCH64]
+[Sources.Ia32, Sources.IPF, Sources.EBC]
   SaveLongModeContext.c
+  CapsuleReset.c
 
 [Sources.X64]
   X64/SaveLongModeContext.c
+  CapsuleReset.c
+
+[Sources.ARM, Sources.AARCH64]
+  SaveLongModeContext.c
+  Arm/CapsuleReset.c
 
 [Packages]
   MdePkg/MdePkg.dec
@@ -59,6 +66,9 @@ [LibraryClasses.X64]
   UefiLib
   BaseMemoryLib
 
+[LibraryClasses.ARM, LibraryClasses.AARCH64]
+  CacheMaintenanceLib
+
 [Guids]
   ## SOMETIMES_PRODUCES   ## Variable:L"CapsuleUpdateData" # (Process across reset capsule image) for capsule updated data
   ## SOMETIMES_PRODUCES   ## Variable:L"CapsuleLongModeBuffer" # The long mode buffer used by IA32 Capsule PEIM to call X64 CapsuleCoalesce code to handle >4GB capsule blocks
diff --git a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c
index 216798d1617e..23fd6d59c59e 100644
--- a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c
+++ b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c
@@ -15,22 +15,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 
 **/
 
-#include <Uefi.h>
-
-#include <Protocol/Capsule.h>
-#include <Guid/CapsuleVendor.h>
-#include <Guid/FmpCapsule.h>
-
-#include <Library/DebugLib.h>
-#include <Library/PcdLib.h>
-#include <Library/CapsuleLib.h>
-#include <Library/UefiDriverEntryPoint.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
-#include <Library/UefiRuntimeLib.h>
-#include <Library/BaseLib.h>
-#include <Library/PrintLib.h>
-#include <Library/BaseMemoryLib.h>
+#include "CapsuleService.h"
+
 //
 // Handle for the installation of Capsule Architecture Protocol.
 //
@@ -44,15 +30,6 @@ UINTN       mTimes      = 0;
 UINT32      mMaxSizePopulateCapsule     = 0;
 UINT32      mMaxSizeNonPopulateCapsule  = 0;
 
-/**
-  Create the variable to save the base address of page table and stack
-  for transferring into long mode in IA32 PEI.
-**/
-VOID
-SaveLongModeContext (
-  VOID
-  );
-
 /**
   Passes capsules to the firmware with both virtual and physical mapping. Depending on the intended
   consumption, the firmware may process the capsule immediately. If the payload should persist
@@ -194,10 +171,12 @@ UpdateCapsule (
   //
   // Check if the platform supports update capsule across a system reset
   //
-  if (!FeaturePcdGet(PcdSupportUpdateCapsuleReset)) {
+  if (!IsPersistAcrossResetCapsuleSupported ()) {
     return EFI_UNSUPPORTED;
   }
 
+  CapsuleCacheWriteBack (ScatterGatherList);
+
   //
   // Construct variable name CapsuleUpdateData, CapsuleUpdateData1, CapsuleUpdateData2...
   // if user calls UpdateCapsule multiple times.
@@ -344,7 +323,7 @@ QueryCapsuleCapabilities (
     //
     //Check if the platform supports update capsule across a system reset
     //
-    if (!FeaturePcdGet(PcdSupportUpdateCapsuleReset)) {
+    if (!IsPersistAcrossResetCapsuleSupported ()) {
       return EFI_UNSUPPORTED;
     }
     *ResetType = EfiResetWarm;
diff --git a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.h b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.h
new file mode 100644
index 000000000000..85aafc144b41
--- /dev/null
+++ b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.h
@@ -0,0 +1,73 @@
+/** @file
+  Capsule Runtime Driver produces two UEFI capsule runtime services.
+  (UpdateCapsule, QueryCapsuleCapabilities)
+  It installs the Capsule Architectural Protocol defined in PI1.0a to signify 
+  the capsule runtime services are ready.
+
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
+
+  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 <Uefi.h>
+
+#include <Protocol/Capsule.h>
+#include <Guid/CapsuleVendor.h>
+#include <Guid/FmpCapsule.h>
+
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/CapsuleLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PrintLib.h>
+#include <Library/BaseMemoryLib.h>
+
+/**
+  Create the variable to save the base address of page table and stack
+  for transferring into long mode in IA32 PEI.
+**/
+VOID
+SaveLongModeContext (
+  VOID
+  );
+
+/**
+  Whether the platform supports capsules that persist across reset. Note that
+  some platforms only support such capsules at boot time.
+
+  @return TRUE  if a PersistAcrossReset capsule may be passed to UpdateCapsule()
+                at this time
+          FALSE otherwise
+**/
+BOOLEAN
+EFIAPI
+IsPersistAcrossResetCapsuleSupported (
+  VOID
+  );
+
+/**
+  Writes Back a range of data cache lines covering a set of capsules in memory.
+
+  Writes Back the data cache lines specified by ScatterGatherList.
+
+  @param  ScatterGatherList Physical address of the data structure that
+                            describes a set of capsules in memory
+
+**/
+VOID
+EFIAPI
+CapsuleCacheWriteBack (
+  IN  EFI_PHYSICAL_ADDRESS    ScatterGatherList
+  );
