diff --git a/Makefile b/Makefile
index 4f9184f4a4c483e00415c73748ce9badcd5fb9d5..bfd31b0236f300e07135548fef85eac26b05dfb4 100644
--- a/Makefile
+++ b/Makefile
@@ -2286,7 +2286,7 @@ $(GENDIR)/src/proto/grpc/testing/compiler_test.pb.cc: src/proto/grpc/testing/com
 $(GENDIR)/src/proto/grpc/testing/compiler_test.grpc.pb.cc: src/proto/grpc/testing/compiler_test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
 	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
+	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=generate_mock_code=true:$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
 endif
 
 ifeq ($(NO_PROTOC),true)
diff --git a/bazel/cc_grpc_library.bzl b/bazel/cc_grpc_library.bzl
index ab1add476e1cbcb50237eaf5b669d69b90b5e958..03a092192f801136d64996886b83361ef26391da 100644
--- a/bazel/cc_grpc_library.bzl
+++ b/bazel/cc_grpc_library.bzl
@@ -2,7 +2,7 @@
 
 load("//:bazel/generate_cc.bzl", "generate_cc")
 
-def cc_grpc_library(name, srcs, deps, proto_only, well_known_protos, use_external = False, **kwargs):
+def cc_grpc_library(name, srcs, deps, proto_only, well_known_protos, generate_mock, use_external = False, **kwargs):
   """Generates C++ grpc classes from a .proto file.
 
   Assumes the generated classes will be used in cc_api_version = 2.
@@ -17,6 +17,7 @@ def cc_grpc_library(name, srcs, deps, proto_only, well_known_protos, use_externa
         "@submodule_protobuf//:well_known_protos"
       use_external: When True the grpc deps are prefixed with //external. This
         allows grpc to be used as a dependency in other bazel projects.
+      generate_mock: When true GMOCk code for client stub is generated.
       **kwargs: rest of arguments, e.g., compatible_with and visibility.
   """
   if len(srcs) > 1:
@@ -54,6 +55,7 @@ def cc_grpc_library(name, srcs, deps, proto_only, well_known_protos, use_externa
         srcs = [proto_target],
         plugin = plugin,
         well_known_protos = well_known_protos,
+        generate_mock = generate_mock,
         **kwargs
     )
 
diff --git a/bazel/generate_cc.bzl b/bazel/generate_cc.bzl
index f3961f0a4197f5e2bb3e0d7ce1857bd120fe3eaf..7dd2c0486b0e02fe0345638b0e73b9b746b9e81d 100644
--- a/bazel/generate_cc.bzl
+++ b/bazel/generate_cc.bzl
@@ -23,7 +23,10 @@ def generate_cc_impl(ctx):
   arguments = []
   if ctx.executable.plugin:
     arguments += ["--plugin=protoc-gen-PLUGIN=" + ctx.executable.plugin.path]
-    arguments += ["--PLUGIN_out=" + ",".join(ctx.attr.flags) + ":" + dir_out]
+    arguments += ["--PLUGIN_out=" + ",".join(ctx.attr.flags)]
+    if ctx.attr.generate_mock:
+      arguments += [",generate_mock_code=true"]
+    arguments += [":" + dir_out]
     additional_input = [ctx.executable.plugin]
   else:
     arguments += ["--cpp_out=" + ",".join(ctx.attr.flags) + ":" + dir_out]
@@ -71,6 +74,10 @@ generate_cc = rule(
         "well_known_protos" : attr.label(
             mandatory = False,
         ),
+        "generate_mock" : attr.bool(
+            default = False,
+            mandatory = False,
+        ),
         "_protoc": attr.label(
             default = Label("//external:protocol_compiler"),
             executable = True,
diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl
index 8b524bd0e52023468a4f1379bc881587ea0e4a17..b49ad3aa597e22a1000257163f26fca5ce418fc6 100644
--- a/bazel/grpc_build_system.bzl
+++ b/bazel/grpc_build_system.bzl
@@ -59,7 +59,7 @@ def grpc_proto_plugin(name, srcs = [], deps = []):
 load("//:bazel/cc_grpc_library.bzl", "cc_grpc_library")
 
 def grpc_proto_library(name, srcs = [], deps = [], well_known_protos = None,
-                       has_services = True, use_external = False):
+                       has_services = True, use_external = False, generate_mock = False):
   cc_grpc_library(
     name = name,
     srcs = srcs,
@@ -67,5 +67,6 @@ def grpc_proto_library(name, srcs = [], deps = [], well_known_protos = None,
     well_known_protos = well_known_protos,
     proto_only = not has_services,
     use_external = use_external,
+    generate_mock = generate_mock,
   )
 
diff --git a/build.yaml b/build.yaml
index 15a08397792eb60c0f3c109068c05bcbb03d2b4a..8fd1b7bad4da61006681e29015d9e18746fd8c8b 100644
--- a/build.yaml
+++ b/build.yaml
@@ -3630,7 +3630,7 @@ targets:
   - grpc
   - gpr
   args:
-  - --generated_file_path=gens/src/proto/grpc/testing/compiler_test.grpc.pb.h
+  - --generated_file_path=gens/src/proto/grpc/testing
 - name: grpc_cli
   build: test
   run: false
diff --git a/src/proto/grpc/testing/BUILD b/src/proto/grpc/testing/BUILD
index 6f3422e4d167a89c50a1c5ae6e1779122fee1ba5..805988c3372efe113333df9fdc326fdf106754b6 100644
--- a/src/proto/grpc/testing/BUILD
+++ b/src/proto/grpc/testing/BUILD
@@ -36,6 +36,7 @@ load("//bazel:grpc_build_system.bzl", "grpc_proto_library")
 grpc_proto_library(
     name = "compiler_test_proto",
     srcs = ["compiler_test.proto"],
+    generate_mock = True,
 )
 
 grpc_proto_library(
@@ -55,6 +56,7 @@ grpc_proto_library(
     name = "echo_proto",
     srcs = ["echo.proto"],
     deps = ["echo_messages_proto"],
+    generate_mock = True,
 )
 
 grpc_proto_library(
diff --git a/test/cpp/codegen/BUILD b/test/cpp/codegen/BUILD
index 14d5733da2c8181ce641a2928f56a0e433df07c8..43d133fc342fe966b422f8f4b73b54e8bb859ab4 100644
--- a/test/cpp/codegen/BUILD
+++ b/test/cpp/codegen/BUILD
@@ -62,7 +62,7 @@ cc_test(
 cc_test(
     name = "golden_file_test",
     srcs = ["golden_file_test.cc"],
-    args = ["--generated_file_path=$(GENDIR)/src/proto/grpc/testing/compiler_test.grpc.pb.h"],
+    args = ["--generated_file_path=$(GENDIR)/src/proto/grpc/testing/"],
     data = [
         ":compiler_test_golden",
         "//src/proto/grpc/testing:_compiler_test_proto_grpc_codegen",
diff --git a/test/cpp/codegen/compiler_test_mock_golden b/test/cpp/codegen/compiler_test_mock_golden
new file mode 100644
index 0000000000000000000000000000000000000000..ced61aeb94f46f88fc8c6689dd858440cd364528
--- /dev/null
+++ b/test/cpp/codegen/compiler_test_mock_golden
@@ -0,0 +1,49 @@
+// Generated by the gRPC C++ plugin.
+// If you make any local change, they will be lost.
+// source: src/proto/grpc/testing/compiler_test.proto
+
+#include "src/proto/grpc/testing/compiler_test.pb.h"
+#include "src/proto/grpc/testing/compiler_test.grpc.pb.h"
+
+#include <grpc++/impl/codegen/async_stream.h>
+#include <grpc++/impl/codegen/sync_stream.h>
+#include <gmock/gmock.h>
+namespace grpc {
+namespace testing {
+
+// ServiceA detached comment 1
+//
+// ServiceA detached comment 2
+//
+// ServiceA leading comment 1
+class MockServiceAStub : public ServiceA::StubInterface {
+ public:
+  MockServiceAStub(){}
+  ~MockServiceAStub(){}
+  // MethodA1 leading comment 1
+  MOCK_METHOD3(MethodA1, ::grpc::Status(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::testing::Response* response));
+  MOCK_METHOD3(AsyncMethodA1Raw, ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>*(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq));
+  // MethodA1 trailing comment 1
+  // MethodA2 detached leading comment 1
+  //
+  // Method A2 leading comment 1
+  // Method A2 leading comment 2
+  MOCK_METHOD2(MethodA2Raw, ::grpc::ClientWriterInterface< ::grpc::testing::Request>*(::grpc::ClientContext* context, ::grpc::testing::Response* response));
+  MOCK_METHOD4(AsyncMethodA2Raw, ::grpc::ClientAsyncWriterInterface< ::grpc::testing::Request>*(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::CompletionQueue* cq, void* tag));
+  // MethodA2 trailing comment 1
+};
+
+// ServiceB leading comment 1
+class MockServiceBStub : public ServiceB::StubInterface {
+ public:
+  MockServiceBStub(){}
+  ~MockServiceBStub(){}
+  // MethodB1 leading comment 1
+  MOCK_METHOD3(MethodB1, ::grpc::Status(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::testing::Response* response));
+  MOCK_METHOD3(AsyncMethodB1Raw, ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>*(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq));
+  // MethodB1 trailing comment 1
+};
+
+} // namespace grpc
+} // namespace testing
+
diff --git a/test/cpp/codegen/golden_file_test.cc b/test/cpp/codegen/golden_file_test.cc
index 158a4d933c9770d5ee4a18af62edcff1ef3ecacb..dd09471fdb855cdc688d49fe11b994a51a0fe90d 100644
--- a/test/cpp/codegen/golden_file_test.cc
+++ b/test/cpp/codegen/golden_file_test.cc
@@ -37,16 +37,18 @@
 #include <gflags/gflags.h>
 #include <gtest/gtest.h>
 
-DEFINE_string(generated_file_path, "",
-              "path to the generated compiler_test.grpc.pb.h file");
+DEFINE_string(
+    generated_file_path, "",
+    "path to the directory containing generated files compiler_test.grpc.pb.h"
+    "and compiler_test_mock.grpc.pb.h");
 
 const char kGoldenFilePath[] = "test/cpp/codegen/compiler_test_golden";
+const char kMockGoldenFilePath[] = "test/cpp/codegen/compiler_test_mock_golden";
 
-TEST(GoldenFileTest, TestGeneratedFile) {
-  ASSERT_FALSE(FLAGS_generated_file_path.empty());
-
-  std::ifstream generated(FLAGS_generated_file_path);
-  std::ifstream golden(kGoldenFilePath);
+void run_test(std::basic_string<char> generated_file,
+              std::basic_string<char> golden_file) {
+  std::ifstream generated(generated_file);
+  std::ifstream golden(golden_file);
 
   ASSERT_TRUE(generated.good());
   ASSERT_TRUE(golden.good());
@@ -61,8 +63,21 @@ TEST(GoldenFileTest, TestGeneratedFile) {
   golden.close();
 }
 
+TEST(GoldenFileTest, TestGeneratedFile) {
+  run_test(FLAGS_generated_file_path + "compiler_test.grpc.pb.h",
+           kGoldenFilePath);
+}
+
+TEST(GoldenMockFileTest, TestGeneratedMockFile) {
+  run_test(FLAGS_generated_file_path + "compiler_test_mock.grpc.pb.h",
+           kMockGoldenFilePath);
+}
+
 int main(int argc, char **argv) {
   ::testing::InitGoogleTest(&argc, argv);
   ::google::ParseCommandLineFlags(&argc, &argv, true);
+  if (FLAGS_generated_file_path.empty()) return 1;
+  if (FLAGS_generated_file_path.back() != '/')
+    FLAGS_generated_file_path.append("/");
   return RUN_ALL_TESTS();
 }
diff --git a/test/cpp/end2end/mock_test.cc b/test/cpp/end2end/mock_test.cc
index 9c040a0cc37f349b604933c1d20ba419823c53f8..7e330063ed3bec95f7f9ef99e3d5f23fb9e1344f 100644
--- a/test/cpp/end2end/mock_test.cc
+++ b/test/cpp/end2end/mock_test.cc
@@ -186,7 +186,7 @@ class TestServiceImpl : public EchoTestService::Service {
 
   Status RequestStream(ServerContext* context,
                        ServerReader<EchoRequest>* reader,
-                       EchoResponse* response) {
+                       EchoResponse* response) override {
     EchoRequest request;
     grpc::string resp("");
     while (reader->Read(&request)) {
@@ -198,7 +198,7 @@ class TestServiceImpl : public EchoTestService::Service {
   }
 
   Status ResponseStream(ServerContext* context, const EchoRequest* request,
-                        ServerWriter<EchoResponse>* writer) {
+                        ServerWriter<EchoResponse>* writer) override {
     EchoResponse response;
     vector<grpc::string> tokens = split(request->message());
     for (grpc::string token : tokens) {