diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index d3129bd..f2922af 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7034,8 +7034,8 @@ def ext_c99_array_usage : Extension<
 def err_c99_array_usage_cxx : Error<
   "%select{qualifier in |static |}0array size %select{||'[*] '}0is a C99 "
   "feature, not permitted in C++">;
-def err_double_requires_fp64 : Error<
-  "use of type 'double' requires cl_khr_fp64 extension to be enabled">;
+ def err_type_requires_extension : Error<
+  "use of type %0 requires %1 extension to be enabled">;
 def err_int128_unsupported : Error<
   "__int128 is not supported on this target">;
 def err_nsconsumed_attribute_mismatch : Error<
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index 86ca339..1786fee 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -272,7 +272,7 @@ KEYWORD(volatile                    , KEYALL)
 KEYWORD(while                       , KEYALL)
 KEYWORD(_Alignas                    , KEYALL)
 KEYWORD(_Alignof                    , KEYALL)
-KEYWORD(_Atomic                     , KEYALL|KEYNOMS)
+KEYWORD(_Atomic                     , KEYC11|KEYCXX11|KEYNOMS)
 KEYWORD(_Bool                       , KEYNOCXX)
 KEYWORD(_Complex                    , KEYALL)
 KEYWORD(_Generic                    , KEYALL)
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index f3e7b4a..d16cbd7 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -206,6 +206,29 @@ void Sema::Initialize() {
   if (PP.getLangOpts().OpenCL) {
     addImplicitTypedef("sampler_t", Context.OCLSamplerTy);
     addImplicitTypedef("event_t", Context.OCLEventTy);
+    if (getLangOpts().OpenCLVersion >= 200) {
+      addImplicitTypedef("atomic_int", Context.getAtomicType(Context.IntTy));
+      addImplicitTypedef("atomic_uint",
+                         Context.getAtomicType(Context.UnsignedIntTy));
+      addImplicitTypedef("atomic_long", Context.getAtomicType(Context.LongTy));
+      addImplicitTypedef("atomic_ulong",
+                         Context.getAtomicType(Context.UnsignedLongTy));
+      addImplicitTypedef("atomic_float",
+                         Context.getAtomicType(Context.FloatTy));
+      addImplicitTypedef("atomic_double",
+                         Context.getAtomicType(Context.DoubleTy));
+      // OpenCLC v2.0, s6.13.11.6 requires that atomic_flag is implemented as
+      // 32-bit integer and OpenCLC v2.0, s6.1.1 int is always 32-bit wide.
+      addImplicitTypedef("atomic_flag", Context.getAtomicType(Context.IntTy));
+      addImplicitTypedef("atomic_intptr_t",
+                         Context.getAtomicType(Context.getIntPtrType()));
+      addImplicitTypedef("atomic_uintptr_t",
+                         Context.getAtomicType(Context.getUIntPtrType()));
+      addImplicitTypedef("atomic_size_t",
+                         Context.getAtomicType(Context.getSizeType()));
+      addImplicitTypedef("atomic_ptrdiff_t",
+                         Context.getAtomicType(Context.getPointerDiffType()));
+    }
   }
 
   DeclarationName BuiltinVaList = &Context.Idents.get("__builtin_va_list");
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 2b70d07..b5e590b 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -885,7 +885,8 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
       Result = Context.DoubleTy;
 
     if (S.getLangOpts().OpenCL && !S.getOpenCLOptions().cl_khr_fp64) {
-      S.Diag(DS.getTypeSpecTypeLoc(), diag::err_double_requires_fp64);
+      S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_requires_extension)
+          << Result << "cl_khr_fp64";
       declarator.setInvalidType(true);
     }
     break;
@@ -961,6 +962,30 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
           << DS.getSourceRange();
         declarator.setInvalidType(true);
       }
+    } else if (S.getLangOpts().OpenCL) {
+      if (const AtomicType *AT = Result->getAs<AtomicType>()) {
+        const BuiltinType *BT = AT->getValueType()->getAs<BuiltinType>();
+        bool NoExtTypes = BT && (BT->getKind() == BuiltinType::Int ||
+                          BT->getKind() == BuiltinType::UInt ||
+                          BT->getKind() == BuiltinType::Float);
+        if (!S.getOpenCLOptions().cl_khr_int64_base_atomics && !NoExtTypes) {
+          S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_requires_extension)
+              << Result << "cl_khr_int64_base_atomics";
+          declarator.setInvalidType(true);
+        }
+        if (!S.getOpenCLOptions().cl_khr_int64_extended_atomics &&
+            !NoExtTypes) {
+          S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_requires_extension)
+              << Result << "cl_khr_int64_extended_atomics";
+          declarator.setInvalidType(true);
+        }
+        if (!S.getOpenCLOptions().cl_khr_fp64 && BT &&
+            BT->getKind() == BuiltinType::Double) {
+          S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_requires_extension)
+              << Result << "cl_khr_fp64";
+          declarator.setInvalidType(true);
+        }
+      }
     }
 
     // TypeQuals handled by caller.
diff --git a/test/Parser/opencl-atomics-cl20.cl b/test/Parser/opencl-atomics-cl20.cl
new file mode 100644
index 0000000..c62142b
--- /dev/null
+++ b/test/Parser/opencl-atomics-cl20.cl
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only
+// RUN: %clang_cc1 %s -verify  -fsyntax-only -cl-std=CL2.0 -DCL20
+// RUN: %clang_cc1 %s -verify  -fsyntax-only -cl-std=CL2.0 -DCL20 -DEXT
+
+#ifdef EXT
+#pragma OPENCL EXTENSION cl_khr_int64_base_atomics:enable
+#pragma OPENCL EXTENSION cl_khr_int64_extended_atomics:enable
+#pragma OPENCL EXTENSION cl_khr_fp64:enable
+#endif
+
+void atomic_types_test() {
+// OpenCL v2.0 s6.13.11.6 defines supported atomic types.
+  atomic_int i;
+  atomic_uint ui;
+  atomic_long l;
+  atomic_ulong ul;
+  atomic_float f;
+  atomic_double d;
+  atomic_flag fl;
+  atomic_intptr_t ip;
+  atomic_uintptr_t uip;
+  atomic_size_t s;
+  atomic_ptrdiff_t pd;
+// OpenCL v2.0 s6.13.11.8, _Atomic type specifier and _Atomic type qualifier
+// are not supported by OpenCL.
+  _Atomic int i; // expected-error {{use of undeclared identifier '_Atomic'}}
+}
+#ifndef CL20
+// expected-error@-16 {{use of undeclared identifier 'atomic_int'}}
+// expected-error@-16 {{use of undeclared identifier 'atomic_uint'}}
+// expected-error@-16 {{use of undeclared identifier 'atomic_long'}}
+// expected-error@-16 {{use of undeclared identifier 'atomic_ulong'}}
+// expected-error@-16 {{use of undeclared identifier 'atomic_float'}}
+// expected-error@-16 {{use of undeclared identifier 'atomic_double'}}
+// expected-error@-16 {{use of undeclared identifier 'atomic_flag'}}
+// expected-error@-16 {{use of undeclared identifier 'atomic_intptr_t'}}
+// expected-error@-16 {{use of undeclared identifier 'atomic_uintptr_t'}}
+// expected-error@-16 {{use of undeclared identifier 'atomic_size_t'}}
+// expected-error@-16 {{use of undeclared identifier 'atomic_ptrdiff_t'}}
+#elif !EXT
+// expected-error@-26 {{use of type 'atomic_long' (aka '_Atomic(long)') requires cl_khr_int64_base_atomics extension to be enabled}}
+// expected-error@-27 {{use of type 'atomic_long' (aka '_Atomic(long)') requires cl_khr_int64_extended_atomics extension to be enabled}}
+// expected-error@-27 {{use of type 'atomic_ulong' (aka '_Atomic(unsigned long)') requires cl_khr_int64_base_atomics extension to be enabled}}
+// expected-error@-28 {{use of type 'atomic_ulong' (aka '_Atomic(unsigned long)') requires cl_khr_int64_extended_atomics extension to be enabled}}
+// expected-error@-27 {{use of type 'atomic_double' (aka '_Atomic(double)') requires cl_khr_int64_base_atomics extension to be enabled}}
+// expected-error@-28 {{use of type 'atomic_double' (aka '_Atomic(double)') requires cl_khr_int64_extended_atomics extension to be enabled}}
+// expected-error@-29 {{use of type 'atomic_double' (aka '_Atomic(double)') requires cl_khr_fp64 extension to be enabled}}
+// expected-error-re@-28 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}}
+// expected-error-re@-29 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}}
+// expected-error-re@-29 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}}
+// expected-error-re@-30 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}}
+// expected-error-re@-30 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}}
+// expected-error-re@-31 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}}
+// expected-error-re@-31 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}}
+// expected-error-re@-32 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}}
+#endif
diff --git a/test/SemaCXX/atomic-type.cpp b/test/SemaCXX/atomic-type.cpp
index 779b067..da84486 100644
--- a/test/SemaCXX/atomic-type.cpp
+++ b/test/SemaCXX/atomic-type.cpp
@@ -1,4 +1,3 @@
-// RUN: %clang_cc1 -verify -pedantic %s -std=c++98
 // RUN: %clang_cc1 -verify -pedantic %s -std=c++11
 
 template<typename T> struct atomic {
diff --git a/test/SemaCXX/references.cpp b/test/SemaCXX/references.cpp
index cfe7dc1..df49294 100644
--- a/test/SemaCXX/references.cpp
+++ b/test/SemaCXX/references.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
 int g(int);
 
 void f() {
