diff --git a/lib/Headers/altivec.h b/lib/Headers/altivec.h
index 5e27a8327b472e5cdbf92c0b1f6c099df14899a9..eded7b2754effc4781a1baaff18521aa467ebce0 100644
--- a/lib/Headers/altivec.h
+++ b/lib/Headers/altivec.h
@@ -4902,6 +4902,52 @@ vec_perm(vector float __a, vector float __b, vector unsigned char __c)
 #endif
 }
 
+#ifdef __VSX__
+vector long long __ATTRS_o_ai
+vec_perm(vector long long __a, vector long long __b, vector unsigned char __c)
+{
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector long long)__builtin_altivec_vperm_4si(__b, __a, __d);
+#else
+  return (vector long long)__builtin_altivec_vperm_4si(__a, __b, __c);
+#endif
+}
+
+vector unsigned long long __ATTRS_o_ai
+vec_perm(vector unsigned long long __a, vector unsigned long long __b,
+         vector unsigned char __c)
+{
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector unsigned long long)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
+  return (vector unsigned long long)
+           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
+}
+
+vector double __ATTRS_o_ai
+vec_perm(vector double __a, vector double __b, vector unsigned char __c)
+{
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector double)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
+  return (vector double)
+           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
+}
+#endif
+
 /* vec_vperm */
 
 static vector signed char __ATTRS_o_ai
@@ -4974,6 +5020,27 @@ vec_vperm(vector float __a, vector float __b, vector unsigned char __c)
   return vec_perm(__a, __b, __c);
 }
 
+#ifdef __VSX__
+static vector long long __ATTRS_o_ai
+vec_vperm(vector long long __a, vector long long __b, vector unsigned char __c)
+{
+  return vec_perm(__a, __b, __c);
+}
+
+static vector unsigned long long __ATTRS_o_ai
+vec_vperm(vector unsigned long long __a, vector unsigned long long __b,
+          vector unsigned char __c)
+{
+  return vec_perm(__a, __b, __c);
+}
+
+static vector double __ATTRS_o_ai
+vec_vperm(vector double __a, vector double __b, vector unsigned char __c)
+{
+  return vec_perm(__a, __b, __c);
+}
+#endif
+
 /* vec_re */
 
 static vector float __attribute__((__always_inline__))
diff --git a/test/CodeGen/builtins-ppc-vsx.c b/test/CodeGen/builtins-ppc-vsx.c
index a5e3e4f441cdf1383cfe6bface039517db0ab66f..58a8cc32dce30b70b8dd448dea9c1029abbd9221 100644
--- a/test/CodeGen/builtins-ppc-vsx.c
+++ b/test/CodeGen/builtins-ppc-vsx.c
@@ -1,6 +1,8 @@
 // REQUIRES: powerpc-registered-target
 // RUN: %clang_cc1 -faltivec -target-feature +vsx -triple powerpc64-unknown-unknown -emit-llvm %s -o - | FileCheck %s
 
+vector unsigned char vuc = { 8,  9, 10, 11, 12, 13, 14, 15,
+                             0,  1,  2,  3,  4,  5,  6,  7};
 vector float vf = { -1.5, 2.5, -3.5, 4.5 };
 vector double vd = { 3.5, -7.5 };
 vector signed int vsi = { -1, 2, -3, 4 };
@@ -53,6 +55,25 @@ void test1() {
   res_d = __builtin_vsx_xsmindp(d, d);
 // CHECK: @llvm.ppc.vsx.xsmindp
 
+  /* vec_perm */
+  res_vsll = vec_perm(vsll, vsll, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+
+  res_vull = vec_perm(vull, vull, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+
+  res_vd = vec_perm(vd, vd, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+
+  res_vsll = vec_vperm(vsll, vsll, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+
+  res_vull = vec_vperm(vull, vull, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+
+  res_vd = vec_vperm(vd, vd, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+
   /* vec_vsx_ld */
 
   res_vsi = vec_vsx_ld(0, &vsi);