diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index df41aeb..2a77829 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -580,6 +580,13 @@ def Constructor : InheritableAttr {
   let Documentation = [Undocumented];
 }
 
+def Convergent : InheritableAttr {
+  let Spellings = [GNU<"convergent">,
+                   CXX11<"clang", "convergent">];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [ConvergentDocs];
+}
+
 def CUDAConstant : InheritableAttr {
   let Spellings = [GNU<"constant">];
   let Subjects = SubjectList<[Var]>;
diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td
index 39c4257..2b43fcc 100644
--- a/include/clang/Basic/AttrDocs.td
+++ b/include/clang/Basic/AttrDocs.td
@@ -2387,3 +2387,64 @@ def LTOVisibilityDocs : Documentation {
 See :doc:`LTOVisibility`.
   }];
 }
+
+def ConvergentDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+The ``convergent`` attribute can be applied to a function to indicate that the
+callee is dependent on a convergent thread execution pattern under certain
+parallel execution models.
+
+For instance consider the following OpenCL C code:
+
+.. code-block:: c
+
+  void foo0(void);
+  void foo1(void);
+
+  __attribute__((convergent)) void baz() {
+    barrier(CLK_GLOBAL_MEM_FENCE);
+  }
+
+  void bar(int x) {
+    if (x < 5)
+      foo0();
+    else
+      foo1();
+
+    baz();
+
+    if (x < 5)
+      foo0();
+    else
+      foo1();
+  }
+
+All work-items of a specific thread-group must call ``barrier`` in order to
+have a valid OpenCL C program. Moving calls to ``baz`` might generate invalid
+OpenCL programs, like the following:
+
+.. code-block:: c
+
+  void bar(int x) {
+    if (x < 5) {
+      foo0();
+      baz();
+      foo0();
+    } else {
+      foo1();
+      baz();
+      foo1();
+    }
+  }
+
+As the value of ``x`` migth not be the same for all work-items in a work-group,
+hence calls to ``barrier`` might not be performed in the same location for all
+work-items in a given work-group.
+
+The ``convergent`` attribute guarantees that optimizations will not move calls
+to ``baz`` to locations that are not control equivalent to the original
+location in the program, hence it guarantees that calls to ``barrier`` are
+correclty placed.
+  }];
+}
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 50ea7f7..3e69c79 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -1626,6 +1626,8 @@ void CodeGenModule::ConstructAttributeList(
       FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
     if (TargetDecl->hasAttr<NoDuplicateAttr>())
       FuncAttrs.addAttribute(llvm::Attribute::NoDuplicate);
+    if (TargetDecl->hasAttr<ConvergentAttr>())
+      FuncAttrs.addAttribute(llvm::Attribute::Convergent);
 
     if (const FunctionDecl *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
       AddAttributesFromFunctionProtoType(
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index cbc95dc..847ed6c 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -5426,6 +5426,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
   case AttributeList::AT_Constructor:
     handleConstructorAttr(S, D, Attr);
     break;
+  case AttributeList::AT_Convergent:
+    handleSimpleAttribute<ConvergentAttr>(S, D, Attr);
+    break;
   case AttributeList::AT_CXX11NoReturn:
     handleSimpleAttribute<CXX11NoReturnAttr>(S, D, Attr);
     break;
diff --git a/test/CodeGen/attr-convergent.c b/test/CodeGen/attr-convergent.c
new file mode 100644
index 0000000..d759e75
--- /dev/null
+++ b/test/CodeGen/attr-convergent.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.7.0 %s -emit-llvm -o - | FileCheck %s
+
+int f0(void) __attribute__((convergent));
+
+int f1(void) {
+  return f0();
+}
+
+// CHECK: define i32 @f1() [[ATTR_1:#[0-9]+]] {
+// CHECK:   [[RET:%.+]] = call i32 @f0() [[ATTR_CS:#[0-9]+]]
+// CHECK:   ret i32 [[RET]]
+// CHECK: }
+
+// CHECK: declare i32 @f0() [[ATTR_0:#[0-9]+]]
+
+// CHECK-NOT: attributes [[ATTR_1]] = { convergent {{.*}} }
+// CHECK:     attributes [[ATTR_0]] = { convergent {{.*}} }
+// CHECK:     attributes [[ATTR_CS]] = { convergent }
diff --git a/test/Sema/attr-convergent.c b/test/Sema/attr-convergent.c
new file mode 100644
index 0000000..d9a9db9
--- /dev/null
+++ b/test/Sema/attr-convergent.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+int t0 __attribute__((convergent)); // expected-warning {{'convergent' attribute only applies to functions}}
+
+void t1() __attribute__((convergent));
+
+void t2() __attribute__((convergent(2))); // expected-error {{'convergent' attribute takes no arguments}}
