diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp
index aebc69d52..74a0acf1a 100644
--- a/src/core/file_sys/patch_manager.cpp
+++ b/src/core/file_sys/patch_manager.cpp
@@ -11,6 +11,7 @@
 #include "core/file_sys/patch_manager.h"
 #include "core/file_sys/registered_cache.h"
 #include "core/file_sys/romfs.h"
+#include "core/file_sys/vfs_layered.h"
 #include "core/hle/service/filesystem/filesystem.h"
 #include "core/loader/loader.h"
 
@@ -31,8 +32,9 @@ std::string FormatTitleVersion(u32 version, TitleVersionFormat format) {
     return fmt::format("v{}.{}.{}", bytes[3], bytes[2], bytes[1]);
 }
 
-constexpr std::array<const char*, 1> PATCH_TYPE_NAMES{
+constexpr std::array<const char*, 2> PATCH_TYPE_NAMES{
     "Update",
+    "LayeredFS",
 };
 
 std::string FormatPatchTypeName(PatchType type) {
@@ -89,6 +91,41 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset,
         }
     }
 
+    // LayeredFS
+    const auto load_dir = Service::FileSystem::GetModificationLoadRoot(title_id);
+    if (type == ContentRecordType::Program && load_dir != nullptr && load_dir->GetSize() > 0) {
+        const auto extracted = ExtractRomFS(romfs);
+
+        if (extracted != nullptr) {
+            auto patch_dirs = load_dir->GetSubdirectories();
+            std::sort(patch_dirs.begin(), patch_dirs.end(),
+                      [](const VirtualDir& l, const VirtualDir& r) {
+                          return l->GetName() < r->GetName();
+                      });
+
+            std::vector<VirtualDir> layers;
+            layers.reserve(patch_dirs.size() + 1);
+            for (const auto& subdir : patch_dirs) {
+                const auto romfs_dir = subdir->GetSubdirectory("romfs");
+                if (romfs_dir != nullptr)
+                    layers.push_back(romfs_dir);
+            }
+
+            layers.push_back(extracted);
+
+            const auto layered = LayerDirectories(layers);
+
+            if (layered != nullptr) {
+                const auto packed = CreateRomFS(layered);
+
+                if (packed != nullptr) {
+                    LOG_INFO(Loader, "    RomFS: LayeredFS patches applied successfully");
+                    romfs = packed;
+                }
+            }
+        }
+    }
+
     return romfs;
 }
 
@@ -114,6 +151,10 @@ std::map<PatchType, std::string> PatchManager::GetPatchVersionNames() const {
         }
     }
 
+    const auto lfs_dir = Service::FileSystem::GetModificationLoadRoot(title_id);
+    if (lfs_dir != nullptr && lfs_dir->GetSize() > 0)
+        out[PatchType::LayeredFS] = "";
+
     return out;
 }
 
diff --git a/src/core/file_sys/patch_manager.h b/src/core/file_sys/patch_manager.h
index 209cab1dc..464f17515 100644
--- a/src/core/file_sys/patch_manager.h
+++ b/src/core/file_sys/patch_manager.h
@@ -26,6 +26,7 @@ std::string FormatTitleVersion(u32 version,
 
 enum class PatchType {
     Update,
+    LayeredFS,
 };
 
 std::string FormatPatchTypeName(PatchType type);
@@ -42,6 +43,7 @@ public:
 
     // Currently tracked RomFS patches:
     // - Game Updates
+    // - LayeredFS
     VirtualFile PatchRomFS(VirtualFile base, u64 ivfc_offset,
                            ContentRecordType type = ContentRecordType::Program) const;