diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 3eb783c..1a86e02 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -311,6 +311,74 @@
   [(set_attr "type" "no_insn")]
 )
 
+(define_insn "*prefetch"
+  [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
+                      (match_operand:DI 1 "aarch64_prefetch_pimm" "")
+             )
+            (match_operand:QI 2 "const_int_operand" "n")
+           (match_operand:QI 3 "const_int_operand" "n"))]
+  ""
+  "*
+{
+  int locality = INTVAL (operands[3]);
+
+  gcc_assert (IN_RANGE (locality, 0, 3));
+
+  if (locality == 0)
+     /* non temporal locality */
+     return (INTVAL(operands[2])) ? \"prfm\\tPSTL1STRM, [%0, %1]\" : \"prfm\\tPLDL1STRM, [%0, %1]\";
+
+  /* temporal locality */
+  return (INTVAL(operands[2])) ? \"prfm\\tPSTL%3KEEP, [%0, %1]\" : \"prfm\\tPLDL%3KEEP, [%0, %1]\";
+}"
+  [(set_attr "type" "prefetch")]
+)
+
+(define_insn "*prefetch"
+  [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
+                      (match_operand:DI 1 "aarch64_prefetch_unscaled" "")
+             )
+            (match_operand:QI 2 "const_int_operand" "n")
+            (match_operand:QI 3 "const_int_operand" "n"))]
+  ""
+  "*
+{
+  int locality = INTVAL (operands[3]);
+
+  gcc_assert (IN_RANGE (locality, 0, 3));
+
+  if (locality == 0)
+     /* non temporal locality */
+     return (INTVAL(operands[2])) ? \"prfum\\tPSTL1STRM, [%0, %1]\" : \"prfm\\tPLDL1STRM, [%0, %1]\";
+
+  /* temporal locality */
+  return (INTVAL(operands[2])) ? \"prfum\\tPSTL%3KEEP, [%0, %1]\" : \"prfm\\tPLDL%3KEEP, [%0, %1]\";
+}"
+  [(set_attr "type" "prefetch")]
+)
+
+(define_insn "prefetch"
+  [(prefetch (match_operand:DI 0 "address_operand" "r")
+            (match_operand:QI 1 "const_int_operand" "n")
+            (match_operand:QI 2 "const_int_operand" "n"))]
+  ""
+  "*
+{
+  int locality = INTVAL (operands[2]);
+
+  gcc_assert (IN_RANGE (locality, 0, 3));
+
+  if (locality == 0)
+     /* non temporal locality */
+     return (INTVAL(operands[1])) ? \"prfm\\tPSTL1STRM, [%0, #0]\" : \"prfm\\tPLDL1STRM, [%0, #0]\";
+
+  /* temporal locality */
+  return (INTVAL(operands[1])) ? \"prfm\\tPSTL%2KEEP, [%0, #0]\" : \"prfm\\tPLDL%2KEEP, [%0, #0]\";
+}"
+  [(set_attr "type" "prefetch")]
+)
+
+
 (define_insn "trap"
   [(trap_if (const_int 1) (const_int 8))]
   ""
diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
index 2702a3c..c37a8a9 100644
--- a/gcc/config/aarch64/predicates.md
+++ b/gcc/config/aarch64/predicates.md
@@ -66,6 +66,14 @@
   (ior (match_operand 0 "register_operand")
        (match_operand 0 "aarch64_plus_immediate")))
 
+(define_predicate "aarch64_prefetch_pimm"
+  (and (match_code "const_int")
+       (match_test "(INTVAL (op) < 0x7ff8 && (0 == INTVAL (op) % 8))")))
+
+(define_predicate "aarch64_prefetch_unscaled"
+  (and (match_code "const_int")
+       (match_test "(INTVAL (op) < 255 && INTVAL (op) > -256)")))
+
 (define_predicate "aarch64_pluslong_immediate"
   (and (match_code "const_int")
        (match_test "(INTVAL (op) < 0xffffff && INTVAL (op) > -0xffffff)")))
diff --git a/gcc/config/arm/types.md b/gcc/config/arm/types.md
index efbf7a7..0b92c1a 100644
--- a/gcc/config/arm/types.md
+++ b/gcc/config/arm/types.md
@@ -117,6 +117,7 @@
 ; mvn_shift_reg      inverting move instruction, shifted operand by a register.
 ; no_insn            an insn which does not represent an instruction in the
 ;                    final output, thus having no impact on scheduling.
+; prefetch           a prefetch instruction
 ; rbit               reverse bits.
 ; rev                reverse bytes.
 ; sdiv               signed division.
@@ -554,6 +555,7 @@
   call,\
   clz,\
   no_insn,\
+  prefetch,\
   csel,\
   crc,\
   extend,\
