diff --git a/src/core/arm/nce/lru_cache.h b/src/core/arm/nce/lru_cache.h
new file mode 100644
index 0000000000..47125922cb
--- /dev/null
+++ b/src/core/arm/nce/lru_cache.h
@@ -0,0 +1,57 @@
+#pragma once
+
+#include <list>
+#include <unordered_map>
+
+template<typename KeyType, typename ValueType>
+class LRUCache {
+public:
+    explicit LRUCache(size_t capacity) : capacity(capacity) {}
+
+    ValueType* get(const KeyType& key) {
+        auto it = cache_map.find(key);
+        if (it == cache_map.end()) {
+            return nullptr;
+        }
+
+        // Move the accessed item to the front of the list (most recently used)
+        cache_list.splice(cache_list.begin(), cache_list, it->second.first);
+        return &(it->second.second);
+    }
+
+    void put(const KeyType& key, const ValueType& value) {
+        auto it = cache_map.find(key);
+
+        if (it != cache_map.end()) {
+            // Key exists, update value and move to front
+            it->second.second = value;
+            cache_list.splice(cache_list.begin(), cache_list, it->second.first);
+            return;
+        }
+
+        // Remove the least recently used item if cache is full
+        if (cache_map.size() >= capacity) {
+            auto last = cache_list.back();
+            cache_map.erase(last);
+            cache_list.pop_back();
+        }
+
+        // Insert new item at the front
+        cache_list.push_front(key);
+        cache_map[key] = {cache_list.begin(), value};
+    }
+
+    void clear() {
+        cache_map.clear();
+        cache_list.clear();
+    }
+
+    size_t size() const {
+        return cache_map.size();
+    }
+
+private:
+    size_t capacity;
+    std::list<KeyType> cache_list;
+    std::unordered_map<KeyType, std::pair<typename std::list<KeyType>::iterator, ValueType>> cache_map;
+};
\ No newline at end of file
diff --git a/src/core/arm/nce/patcher.h b/src/core/arm/nce/patcher.h
index a44f385e2e..21ea7fd2a1 100644
--- a/src/core/arm/nce/patcher.h
+++ b/src/core/arm/nce/patcher.h
@@ -13,6 +13,7 @@
 #include "core/hle/kernel/code_set.h"
 #include "core/hle/kernel/k_typed_address.h"
 #include "core/hle/kernel/physical_memory.h"
+#include "lru_cache.h"
 
 namespace Core::NCE {
 
@@ -60,8 +61,20 @@ private:
     void WriteCntpctHandler(ModuleDestLabel module_dest, oaknut::XReg dest_reg);
 
 private:
+    static constexpr size_t CACHE_SIZE = 1024;  // Cache size for patch entries
+    LRUCache<uintptr_t, PatchTextAddress> patch_cache{CACHE_SIZE};
+
     void BranchToPatch(uintptr_t module_dest) {
-        curr_patch->m_branch_to_patch_relocations.push_back({c.offset(), module_dest});
+        // Try to get existing patch entry from cache
+        if (auto* cached_patch = patch_cache.get(module_dest)) {
+            curr_patch->m_branch_to_patch_relocations.push_back({c.offset(), *cached_patch});
+            return;
+        }
+
+        // If not in cache, create new entry and cache it
+        const auto patch_addr = c.offset();
+        curr_patch->m_branch_to_patch_relocations.push_back({patch_addr, module_dest});
+        patch_cache.put(module_dest, patch_addr);
     }
 
     void BranchToModule(uintptr_t module_dest) {