Index: test/CodeGenOpenCL/kernel-arg-info.cl
===================================================================
--- test/CodeGenOpenCL/kernel-arg-info.cl	(revision 0)
+++ test/CodeGenOpenCL/kernel-arg-info.cl	(revision 0)
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -cl-kernel-arg-info -emit-llvm -o - | FileCheck %s
+
+kernel void foo(int *X, int Y, int anotherArg) {
+  *X = Y + anotherArg;
+}
+
+// CHECK: metadata !{metadata !"kernel_arg_name", metadata !"X", metadata !"Y", metadata !"anotherArg"}
Index: include/clang/Frontend/CodeGenOptions.h
===================================================================
--- include/clang/Frontend/CodeGenOptions.h	(revision 159166)
+++ include/clang/Frontend/CodeGenOptions.h	(working copy)
@@ -64,6 +64,7 @@
                                   ///< subroutine.
   unsigned EmitGcovArcs      : 1; ///< Emit coverage data files, aka. GCDA.
   unsigned EmitGcovNotes     : 1; ///< Emit coverage "notes" files, aka GCNO.
+  unsigned EmitOpenCLArgMetadata : 1; /// Emit OpenCL kernel arg metadata.
   unsigned ForbidGuardVariables : 1; ///< Issue errors if C++ guard variables
                                      ///< are required
   unsigned FunctionSections  : 1; ///< Set when -ffunction-sections is enabled
@@ -189,6 +190,7 @@
     EmitDeclMetadata = 0;
     EmitGcovArcs = 0;
     EmitGcovNotes = 0;
+    EmitOpenCLArgMetadata = 0;
     ForbidGuardVariables = 0;
     FunctionSections = 0;
     HiddenWeakTemplateVTables = 0;
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td	(revision 159166)
+++ include/clang/Driver/Options.td	(working copy)
@@ -39,6 +39,7 @@
 def m_Group               : OptionGroup<"<m group>">, Group<CompileOnly_Group>;
 def m_x86_Features_Group  : OptionGroup<"<m x86 features group>">, Group<m_Group>;
 def m_hexagon_Features_Group  : OptionGroup<"<m hexagon features group>">, Group<m_Group>;
+def opencl_Group          : OptionGroup<"<opencl group>">;
 def u_Group               : OptionGroup<"<u group>">;
 
 def pedantic_Group        : OptionGroup<"<pedantic group>">,
@@ -247,6 +248,8 @@
 def bundle__loader : Separate<"-bundle_loader">;
 def bundle : Flag<"-bundle">;
 def b : JoinedOrSeparate<"-b">, Flags<[Unsupported]>;
+def cl_kernel_arg_info : Flag<"-cl-kernel-arg-info">, Flags<[CC1Option]>, Group<opencl_Group>,
+HelpText<"OpenCL only. This option allows the compiler to store information about the arguments of a kernel(s)"> ;
 def client__name : JoinedOrSeparate<"-client_name">;
 def combine : Flag<"-combine">, Flags<[DriverOption, Unsupported]>;
 def compatibility__version : JoinedOrSeparate<"-compatibility_version">;
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp	(revision 159166)
+++ lib/Frontend/CompilerInvocation.cpp	(working copy)
@@ -210,6 +210,8 @@
     Res.push_back("-femit-coverage-data");
   if (Opts.EmitGcovNotes)
     Res.push_back("-femit-coverage-notes");
+  if (Opts.EmitOpenCLArgMetadata)
+    Res.push_back("-cl-kernel-arg-info");
   if (!Opts.MergeAllConstants)
     Res.push_back("-fno-merge-all-constants");
   if (Opts.NoCommon)
@@ -1232,6 +1234,7 @@
   Opts.InstrumentForProfiling = Args.hasArg(OPT_pg);
   Opts.EmitGcovArcs = Args.hasArg(OPT_femit_coverage_data);
   Opts.EmitGcovNotes = Args.hasArg(OPT_femit_coverage_notes);
+  Opts.EmitOpenCLArgMetadata = Args.hasArg(OPT_cl_kernel_arg_info);
   Opts.CoverageFile = Args.getLastArgValue(OPT_coverage_file);
   Opts.DebugCompilationDir = Args.getLastArgValue(OPT_fdebug_compilation_dir);
   Opts.LinkBitcodeFile = Args.getLastArgValue(OPT_mlink_bitcode_file);
Index: lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- lib/CodeGen/CodeGenFunction.cpp	(revision 159166)
+++ lib/CodeGen/CodeGenFunction.cpp	(working copy)
@@ -251,6 +251,56 @@
   Builder.CreateCall(MCountFn);
 }
 
+// OpenCL v1.2 s5.6.4.6 allows the compiler to store kernel arg
+// information in the program executeable. The argument information store
+// includes the argument name, its type, the address and access qualifiers used.
+// FIXME: Add type, address, and access qualifiers.
+static void GenOpenCLArgMetaData(const FunctionDecl *FD, llvm::Function *Fn,
+                                 CodeGenModule &CGM,
+                                 llvm::LLVMContext &Context,
+                                 llvm::SmallVector <llvm::Value*, 5> &kernelMDArgs) {
+  
+  // Create MDNodes that represents the kernel arg metadata.
+  // Each MDNode is a list in the form of "key", N number of values which is
+  // the same number of values as their are kernel arguments.
+  
+  // Metadata for arg name.
+  SmallVector<llvm::Value*, 8> argNames;
+  argNames.push_back(llvm::MDString::get(Context, "kernel_arg_name"));
+  
+  for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) {
+    
+    const ParmVarDecl *parm = FD->getParamDecl(i);
+    
+    // Get arg name.
+    argNames.push_back(llvm::MDString::get(Context, parm->getName()));
+    
+  }
+  // Add MDNode to the list of all metadata.
+  kernelMDArgs.push_back(llvm::MDNode::get(Context, argNames));
+}
+
+void CodeGenFunction::EmitOpenCLKernelMetadata(const FunctionDecl *FD, 
+                                               llvm::Function *Fn)
+{
+  if (!FD->hasAttr<OpenCLKernelAttr>())
+    return;
+  
+  llvm::LLVMContext &Context = getLLVMContext();
+  
+  llvm::SmallVector <llvm::Value*, 5> kernelMDArgs;
+  kernelMDArgs.push_back(Fn);
+  
+  if (CGM.getCodeGenOpts().EmitOpenCLArgMetadata)
+    GenOpenCLArgMetaData(FD, Fn, CGM, Context, kernelMDArgs);
+  
+  llvm::MDNode *kernelMDNode = llvm::MDNode::get(Context, kernelMDArgs);
+  llvm::NamedMDNode *OpenCLKernelMetadata =
+  CGM.getModule().getOrInsertNamedMetadata("opencl.kernels");
+  OpenCLKernelMetadata->addOperand(kernelMDNode);
+}
+
+
 void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
                                     llvm::Function *Fn,
                                     const CGFunctionInfo &FnInfo,
@@ -279,14 +329,7 @@
   if (getContext().getLangOpts().OpenCL) {
     // Add metadata for a kernel function.
     if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
-      if (FD->hasAttr<OpenCLKernelAttr>()) {
-        llvm::LLVMContext &Context = getLLVMContext();
-        llvm::NamedMDNode *OpenCLMetadata = 
-          CGM.getModule().getOrInsertNamedMetadata("opencl.kernels");
-          
-        llvm::Value *Op = Fn;
-        OpenCLMetadata->addOperand(llvm::MDNode::get(Context, Op));
-      }
+      EmitOpenCLKernelMetadata(FD, Fn);
   }
 
   llvm::BasicBlock *EntryBB = createBasicBlock("entry", CurFn);
Index: lib/CodeGen/CodeGenFunction.h
===================================================================
--- lib/CodeGen/CodeGenFunction.h	(revision 159166)
+++ lib/CodeGen/CodeGenFunction.h	(working copy)
@@ -2532,6 +2532,9 @@
   llvm::MDNode *getRangeForLoadFromType(QualType Ty);
   void EmitReturnOfRValue(RValue RV, QualType Ty);
 
+  void EmitOpenCLKernelMetadata(const FunctionDecl *FD, 
+                                llvm::Function *Fn);
+  
   /// ExpandTypeFromArgs - Reconstruct a structure of type \arg Ty
   /// from function arguments into \arg Dst. See ABIArgInfo::Expand.
   ///
