diff --git a/src/core/core.cpp b/src/core/core.cpp
index 7e969f20a3..7d04abf03f 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -263,6 +263,18 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st
         return ResultStatus::ErrorGetLoader;
     }
 
+    if (restore_plugin_context.has_value() && restore_plugin_context->is_enabled &&
+        restore_plugin_context->use_user_load_parameters) {
+        u64_le program_id = 0;
+        app_loader->ReadProgramId(program_id);
+        if (restore_plugin_context->user_load_parameters.low_title_Id ==
+                static_cast<u32_le>(program_id) &&
+            restore_plugin_context->user_load_parameters.plugin_memory_strategy ==
+                Service::PLGLDR::PLG_LDR::PluginMemoryStrategy::PLG_STRATEGY_MODE3) {
+            app_loader->SetKernelMemoryModeOverride(Kernel::MemoryMode::Dev2);
+        }
+    }
+
     auto memory_mode = app_loader->LoadKernelMemoryMode();
     if (memory_mode.second != Loader::ResultStatus::Success) {
         LOG_CRITICAL(Core, "Failed to determine system mode (Error {})!",
diff --git a/src/core/hle/service/apt/applet_manager.cpp b/src/core/hle/service/apt/applet_manager.cpp
index 0d657cd9f3..368d2b7ae1 100644
--- a/src/core/hle/service/apt/applet_manager.cpp
+++ b/src/core/hle/service/apt/applet_manager.cpp
@@ -574,7 +574,7 @@ Result AppletManager::PrepareToStartLibraryApplet(AppletId applet_id) {
 
     if (Settings::values.lle_applets) {
         auto cfg = Service::CFG::GetModule(system);
-        auto process = NS::LaunchTitle(FS::MediaType::NAND,
+        auto process = NS::LaunchTitle(system, FS::MediaType::NAND,
                                        GetTitleIdForApplet(applet_id, cfg->GetRegionValue()));
         if (process) {
             return ResultSuccess;
@@ -603,7 +603,7 @@ Result AppletManager::PreloadLibraryApplet(AppletId applet_id) {
 
     if (Settings::values.lle_applets) {
         auto cfg = Service::CFG::GetModule(system);
-        auto process = NS::LaunchTitle(FS::MediaType::NAND,
+        auto process = NS::LaunchTitle(system, FS::MediaType::NAND,
                                        GetTitleIdForApplet(applet_id, cfg->GetRegionValue()));
         if (process) {
             return ResultSuccess;
@@ -815,7 +815,7 @@ Result AppletManager::StartSystemApplet(AppletId applet_id, std::shared_ptr<Kern
         applet_id == AppletId::HomeMenu ? AppletSlot::HomeMenu : AppletSlot::SystemApplet;
     if (!GetAppletSlot(slot_id)->registered) {
         auto cfg = Service::CFG::GetModule(system);
-        auto process = NS::LaunchTitle(FS::MediaType::NAND,
+        auto process = NS::LaunchTitle(system, FS::MediaType::NAND,
                                        GetTitleIdForApplet(applet_id, cfg->GetRegionValue()));
         if (!process) {
             // TODO: Find the right error code.
@@ -1346,8 +1346,8 @@ Result AppletManager::StartApplication(const std::vector<u8>& parameter,
     active_slot = AppletSlot::Application;
 
     // Launch the title directly.
-    auto process =
-        NS::LaunchTitle(app_start_parameters->next_media_type, app_start_parameters->next_title_id);
+    auto process = NS::LaunchTitle(system, app_start_parameters->next_media_type,
+                                   app_start_parameters->next_title_id);
     if (!process) {
         LOG_CRITICAL(Service_APT, "Failed to launch title during application start, exiting.");
         system.RequestShutdown();
@@ -1423,7 +1423,7 @@ void AppletManager::EnsureHomeMenuLoaded() {
 
     auto cfg = Service::CFG::GetModule(system);
     auto menu_title_id = GetTitleIdForApplet(AppletId::HomeMenu, cfg->GetRegionValue());
-    auto process = NS::LaunchTitle(FS::MediaType::NAND, menu_title_id);
+    auto process = NS::LaunchTitle(system, FS::MediaType::NAND, menu_title_id);
     if (!process) {
         LOG_WARNING(Service_APT,
                     "The Home Menu failed to launch, application jumping will not work.");
diff --git a/src/core/hle/service/apt/ns.cpp b/src/core/hle/service/apt/ns.cpp
index 5e859799bb..c71c234195 100644
--- a/src/core/hle/service/apt/ns.cpp
+++ b/src/core/hle/service/apt/ns.cpp
@@ -9,7 +9,8 @@
 
 namespace Service::NS {
 
-std::shared_ptr<Kernel::Process> LaunchTitle(FS::MediaType media_type, u64 title_id) {
+std::shared_ptr<Kernel::Process> LaunchTitle(Core::System& system, FS::MediaType media_type,
+                                             u64 title_id) {
     std::string path = AM::GetTitleContentPath(media_type, title_id);
     auto loader = Loader::GetLoader(path);
 
@@ -18,6 +19,17 @@ std::shared_ptr<Kernel::Process> LaunchTitle(FS::MediaType media_type, u64 title
         return nullptr;
     }
 
+    auto plg_ldr = Service::PLGLDR::GetService(system);
+    if (plg_ldr) {
+        const auto& plg_context = plg_ldr->GetPluginLoaderContext();
+        if (plg_context.is_enabled && plg_context.use_user_load_parameters &&
+            plg_context.user_load_parameters.low_title_Id == static_cast<u32>(title_id) &&
+            plg_context.user_load_parameters.plugin_memory_strategy ==
+                PLGLDR::PLG_LDR::PluginMemoryStrategy::PLG_STRATEGY_MODE3) {
+            loader->SetKernelMemoryModeOverride(Kernel::MemoryMode::Dev2);
+        }
+    }
+
     std::shared_ptr<Kernel::Process> process;
     Loader::ResultStatus result = loader->Load(process);
 
diff --git a/src/core/hle/service/apt/ns.h b/src/core/hle/service/apt/ns.h
index 89fddbd332..8fa80e11b1 100644
--- a/src/core/hle/service/apt/ns.h
+++ b/src/core/hle/service/apt/ns.h
@@ -16,7 +16,8 @@ class System;
 namespace Service::NS {
 
 /// Loads and launches the title identified by title_id in the specified media type.
-std::shared_ptr<Kernel::Process> LaunchTitle(FS::MediaType media_type, u64 title_id);
+std::shared_ptr<Kernel::Process> LaunchTitle(Core::System& system, FS::MediaType media_type,
+                                             u64 title_id);
 
 /// Reboots the system to the specified title.
 void RebootToTitle(Core::System& system, FS::MediaType media_type, u64 title_id);
diff --git a/src/core/hle/service/plgldr/plgldr.cpp b/src/core/hle/service/plgldr/plgldr.cpp
index 1c1a221da3..8e8d876cfb 100644
--- a/src/core/hle/service/plgldr/plgldr.cpp
+++ b/src/core/hle/service/plgldr/plgldr.cpp
@@ -204,7 +204,10 @@ void PLG_LDR::SetLoadSettings(Kernel::HLERequestContext& ctx) {
     IPC::RequestParser rp(ctx);
 
     plgldr_context.use_user_load_parameters = true;
-    plgldr_context.user_load_parameters.no_flash = rp.Pop<u32>() == 1;
+    u32_le flags = rp.Pop<u32>();
+    plgldr_context.user_load_parameters.no_flash = (flags & 1) == 1;
+    plgldr_context.user_load_parameters.plugin_memory_strategy =
+        static_cast<PluginMemoryStrategy>((flags >> 8) & 0xF);
     plgldr_context.user_load_parameters.low_title_Id = rp.Pop<u32>();
 
     auto path = rp.PopMappedBuffer();
diff --git a/src/core/hle/service/plgldr/plgldr.h b/src/core/hle/service/plgldr/plgldr.h
index 2403242382..d9941adbe3 100644
--- a/src/core/hle/service/plgldr/plgldr.h
+++ b/src/core/hle/service/plgldr/plgldr.h
@@ -33,10 +33,16 @@ namespace Service::PLGLDR {
 
 class PLG_LDR final : public ServiceFramework<PLG_LDR> {
 public:
+    enum class PluginMemoryStrategy : u8 {
+        PLG_STRATEGY_NONE = 2,
+        PLG_STRATEGY_SWAP = 0,
+        PLG_STRATEGY_MODE3 = 1,
+    };
+
     struct PluginLoaderContext {
         struct PluginLoadParameters {
             u8 no_flash = 0;
-            u8 no_IR_Patch = 0;
+            PluginMemoryStrategy plugin_memory_strategy = PluginMemoryStrategy::PLG_STRATEGY_SWAP;
             u32_le low_title_Id = 0;
             char path[256] = {0};
             u32_le config[32] = {0};
@@ -44,7 +50,7 @@ class PLG_LDR final : public ServiceFramework<PLG_LDR> {
             template <class Archive>
             void serialize(Archive& ar, const unsigned int) {
                 ar& no_flash;
-                ar& no_IR_Patch;
+                ar& plugin_memory_strategy;
                 ar& low_title_Id;
                 ar& path;
                 ar& config;
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h
index fd76e1cb61..7370752496 100644
--- a/src/core/loader/loader.h
+++ b/src/core/loader/loader.h
@@ -117,6 +117,14 @@ class AppLoader : NonCopyable {
         return std::make_pair(0x2, ResultStatus::Success);
     }
 
+    /**
+     * Forces the application memory mode to the specified value,
+     * overriding the memory mode specified in the metadata.
+     */
+    void SetKernelMemoryModeOverride(Kernel::MemoryMode mem_override) {
+        memory_mode_override = mem_override;
+    }
+
     /**
      * Loads the memory mode that this application needs.
      * This function defaults to Dev1 (96MB allocated to the application) if it can't read the
@@ -124,6 +132,9 @@ class AppLoader : NonCopyable {
      * @returns A pair with the optional memory mode, and the status.
      */
     virtual std::pair<std::optional<Kernel::MemoryMode>, ResultStatus> LoadKernelMemoryMode() {
+        if (memory_mode_override.has_value()) {
+            return std::make_pair(*memory_mode_override, ResultStatus::Success);
+        }
         // 96MB allocated to the application.
         return std::make_pair(Kernel::MemoryMode::Dev1, ResultStatus::Success);
     }
@@ -257,6 +268,7 @@ class AppLoader : NonCopyable {
     Core::System& system;
     FileUtil::IOFile file;
     bool is_loaded = false;
+    std::optional<Kernel::MemoryMode> memory_mode_override = std::nullopt;
 };
 
 /**
diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp
index 695a612f46..6b58dc547f 100644
--- a/src/core/loader/ncch.cpp
+++ b/src/core/loader/ncch.cpp
@@ -69,6 +69,9 @@ std::pair<std::optional<Kernel::MemoryMode>, ResultStatus> AppLoader_NCCH::LoadK
             return std::make_pair(std::nullopt, res);
         }
     }
+    if (memory_mode_override.has_value()) {
+        return std::make_pair(memory_mode_override, ResultStatus::Success);
+    }
 
     // Provide the memory mode from the exheader.
     auto& ncch_caps = overlay_ncch->exheader_header.arm11_system_local_caps;
@@ -159,7 +162,7 @@ ResultStatus AppLoader_NCCH::LoadExec(std::shared_ptr<Kernel::Process>& process)
         // APPLICATION. See:
         // https://github.com/LumaTeam/Luma3DS/blob/e2778a45/sysmodules/pm/source/launch.c#L237
         auto& ncch_caps = overlay_ncch->exheader_header.arm11_system_local_caps;
-        const auto o3ds_mode = static_cast<Kernel::MemoryMode>(ncch_caps.system_mode.Value());
+        const auto o3ds_mode = *LoadKernelMemoryMode().first;
         const auto n3ds_mode = static_cast<Kernel::New3dsMemoryMode>(ncch_caps.n3ds_mode);
         const bool is_new_3ds = Settings::values.is_new_3ds.GetValue();
         if (is_new_3ds && n3ds_mode == Kernel::New3dsMemoryMode::Legacy &&