diff --git a/include/llvm/IntrinsicsARM.td b/include/llvm/IntrinsicsARM.td
index 3954412..8bd2080 100644
--- a/include/llvm/IntrinsicsARM.td
+++ b/include/llvm/IntrinsicsARM.td
@@ -87,6 +87,14 @@ let TargetPrefix = "arm" in {  // All intrinsics start with "llvm.arm.".
 }
 
 //===----------------------------------------------------------------------===//
+// Instruction Prefetch
+
+let TargetPrefix = "arm" in {  // All intrinsics start with "llvm.arm.".
+  def int_arm_pli : GCCBuiltin<"__builtin_arm_pli">,
+    Intrinsic<[], [llvm_ptr_ty], [IntrReadWriteArgMem]>;
+}
+
+//===----------------------------------------------------------------------===//
 // Advanced SIMD (NEON)
 
 let TargetPrefix = "arm" in {  // All intrinsics start with "llvm.arm.".
diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td
index 1340012..309e0a0 100644
--- a/lib/Target/ARM/ARMInstrFormats.td
+++ b/lib/Target/ARM/ARMInstrFormats.td
@@ -1216,6 +1216,11 @@ class T2v6Pat<dag pattern, dag result> : Pat<pattern, result> {
   list<Predicate> Predicates = [IsThumb2, HasV6T2];
 }
 
+// T2v7Pat - Same as Pat<>, but requires V7 Thumb2 mode.
+class T2v7Pat<dag pattern, dag result> : Pat<pattern, result> {
+  list<Predicate> Predicates = [IsThumb2, HasV7];
+}
+
 // T2Pat - Same as Pat<>, but requires that the compiler be in Thumb2 mode.
 class T2Pat<dag pattern, dag result> : Pat<pattern, result> {
   list<Predicate> Predicates = [IsThumb2];
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index e9e11b0..bfcafad 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -1192,6 +1192,11 @@ defm PLD  : APreLoad<1, 1, "pld">,  Requires<[IsARM]>;
 defm PLDW : APreLoad<0, 1, "pldw">, Requires<[IsARM,HasV7,HasMP]>;
 defm PLI  : APreLoad<1, 0, "pli">,  Requires<[IsARM,HasV7]>;
 
+// The ARMPreload only supports data prefetching, a specific intrinsic must be
+// used to emit the PLI instruction.
+def : ARMPat<(int_arm_pli addrmode_imm12:$addr),
+             (PLIi12 addrmode_imm12:$addr)>;
+
 def SETEND : AXI<(outs),(ins setend_op:$end), MiscFrm, NoItinerary,
                  "setend\t$end",
                  [/* For disassembly only; pattern left blank */]>,
diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td
index b8159f1..08f7c92 100644
--- a/lib/Target/ARM/ARMInstrThumb2.td
+++ b/lib/Target/ARM/ARMInstrThumb2.td
@@ -1561,6 +1561,11 @@ defm t2PLD  : T2Ipl<0, 0, "pld">,  Requires<[IsThumb2]>;
 defm t2PLDW : T2Ipl<1, 0, "pldw">, Requires<[IsThumb2,HasV7,HasMP]>;
 defm t2PLI  : T2Ipl<0, 1, "pli">,  Requires<[IsThumb2,HasV7]>;
 
+// The ARMPreload only supports data prefetching, a specific intrinsic must be
+// used to emit the PLI instruction.
+def : T2v7Pat<(int_arm_pli t2addrmode_imm12:$addr),
+              (t2PLIi12 t2addrmode_imm12:$addr)>;
+
 //===----------------------------------------------------------------------===//
 //  Load / store multiple Instructions.
 //
diff --git a/test/CodeGen/ARM/pli.ll b/test/CodeGen/ARM/pli.ll
new file mode 100644
index 0000000..c690691
--- /dev/null
+++ b/test/CodeGen/ARM/pli.ll
@@ -0,0 +1,11 @@
+; RUN: llc < %s -mtriple=armv7-apple-darwin   | FileCheck %s
+; RUN: llc < %s -mtriple=thumbv7-apple-darwin | FileCheck %s
+
+; CHECK: pli [
+define void @f0(i8* %a) nounwind {
+entry:
+  tail call void @llvm.arm.pli(i8* %a)
+  ret void
+}
+
+declare void @llvm.arm.pli(i8*) nounwind
