diff --git a/src/frontend/decoder/arm.h b/src/frontend/decoder/arm.h
index 15cfa982..72de5e93 100644
--- a/src/frontend/decoder/arm.h
+++ b/src/frontend/decoder/arm.h
@@ -177,8 +177,8 @@ boost::optional<const ArmMatcher<V>&> DecodeArm(u32 instruction) {
         //INST(&V::arm_SWPB,        "SWPB",                "cccc00010100nnnndddd00001001mmmm"), // v2S (v6: Deprecated)
 
         // Load/Store instructions
-        //INST(&V::arm_LDR_imm,     "LDR (imm)",           "cccc010pu0w1nnnnddddvvvvvvvvvvvv"),
-        //INST(&V::arm_LDR_reg,     "LDR (reg)",           "cccc011pu0w1nnnnddddvvvvvrr0mmmm"),
+        INST(&V::arm_LDR_imm,     "LDR (imm)",           "cccc010pu0w1nnnnddddvvvvvvvvvvvv"),
+        INST(&V::arm_LDR_reg,     "LDR (reg)",           "cccc011pu0w1nnnnddddvvvvvrr0mmmm"),
         //INST(&V::arm_LDRB_imm,    "LDRB (imm)",          "cccc010pu1w1nnnnddddvvvvvvvvvvvv"),
         //INST(&V::arm_LDRB_reg,    "LDRB (reg)",          "cccc011pu1w1nnnnddddvvvvvrr0mmmm"),
         //INST(&V::arm_LDRBT,       "LDRBT (A1)",          "cccc0100u111nnnnttttvvvvvvvvvvvv"),
diff --git a/src/frontend/translate/translate_arm/load_store.cpp b/src/frontend/translate/translate_arm/load_store.cpp
index 1d7df9fd..e5a600ce 100644
--- a/src/frontend/translate/translate_arm/load_store.cpp
+++ b/src/frontend/translate/translate_arm/load_store.cpp
@@ -9,12 +9,66 @@
 namespace Dynarmic {
 namespace Arm {
 
+static IR::Value GetAddressingMode(IREmitter& ir, bool P, bool U, bool W, Reg n, IR::Value index) {
+    IR::Value address;
+    if (P) {
+        // Pre-indexed addressing
+        if (n == Reg::PC && index.IsImmediate()) {
+            address = U ? ir.Imm32(ir.AlignPC(4) + index.GetU32()) : ir.Imm32(ir.AlignPC(4) - index.GetU32());
+        } else {
+            address = U ? ir.Add(ir.GetRegister(n), index) : ir.Sub(ir.GetRegister(n), index);
+        }
+
+        // Wrote calculated address back to the base register
+        if (W) {
+            ir.SetRegister(n, address);
+        }
+    } else {
+        // Post-indexed addressing
+        address = (n == Reg::PC) ? ir.Imm32(ir.AlignPC(4)) : ir.GetRegister(n);
+
+        if (U) {
+            ir.SetRegister(n, ir.Add(ir.GetRegister(n), index));
+        } else {
+            ir.SetRegister(n, ir.Sub(ir.GetRegister(n), index));
+        }
+
+        // TODO(bunnei): Handle W=1 mode, which in this scenario does an unprivileged (User mode) access.
+    }
+    return address;
+}
+
 bool ArmTranslatorVisitor::arm_LDR_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Imm12 imm12) {
-    return InterpretThisInstruction();
+    if (ConditionPassed(cond)) {
+        const auto data = ir.ReadMemory32(GetAddressingMode(ir, P, U, W, n, ir.Imm32(imm12)));
+
+        if (d == Reg::PC) {
+            ir.BXWritePC(data);
+            ir.SetTerm(IR::Term::ReturnToDispatch{});
+            return false;
+        }
+
+        ir.SetRegister(d, data);
+    }
+
+    return true;
 }
 
 bool ArmTranslatorVisitor::arm_LDR_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m) {
-    return InterpretThisInstruction();
+    if (ConditionPassed(cond)) {
+        const auto shifted = EmitImmShift(ir.GetRegister(m), shift, imm5, ir.GetCFlag());
+        const auto data = ir.ReadMemory32(GetAddressingMode(ir, P, U, W, n, shifted.result));
+
+        if (d == Reg::PC) {
+            ir.BXWritePC(data);
+            ir.SetTerm(IR::Term::ReturnToDispatch{});
+            return false;
+        }
+
+        ir.SetRegister(d, data);
+    }
+
+    return true;
 }
 
 bool ArmTranslatorVisitor::arm_LDRB_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Imm12 imm12) {