diff --git a/include/grpc++/client_context.h b/include/grpc++/client_context.h
index 0cf6bdc647e7e8c48ff2faf723e5100a8bc1a5f6..a6e8ccc67c473c89fed5463cb0961a23834761e3 100644
--- a/include/grpc++/client_context.h
+++ b/include/grpc++/client_context.h
@@ -35,8 +35,8 @@
 #define __GRPCPP_CLIENT_CONTEXT_H__
 
 #include <chrono>
+#include <map>
 #include <string>
-#include <vector>
 
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
@@ -49,6 +49,8 @@ struct grpc_completion_queue;
 
 namespace grpc {
 
+class CallOpBuffer;
+
 class ClientContext {
  public:
   ClientContext();
@@ -67,6 +69,7 @@ class ClientContext {
   ClientContext(const ClientContext &);
   ClientContext &operator=(const ClientContext &);
 
+  friend class CallOpBuffer;
   friend class Channel;
   friend class StreamContext;
 
@@ -84,7 +87,7 @@ class ClientContext {
   grpc_call *call_;
   grpc_completion_queue *cq_;
   gpr_timespec absolute_deadline_;
-  std::vector<std::pair<grpc::string, grpc::string> > metadata_;
+  std::multimap<grpc::string, grpc::string> metadata_;
 };
 
 }  // namespace grpc
diff --git a/include/grpc++/impl/call.h b/include/grpc++/impl/call.h
index 141b16ab5bfc5ea2f8e5dbc558da613345ca9ccd..d0cb9024ba629551be62a5dbd089bf7612f9fcc2 100644
--- a/include/grpc++/impl/call.h
+++ b/include/grpc++/impl/call.h
@@ -63,11 +63,13 @@ class CallOpBuffer final : public CompletionQueueTag {
   // Does not take ownership.
   void AddSendInitialMetadata(
       std::multimap<grpc::string, grpc::string> *metadata);
+  void AddSendInitialMetadata(ClientContext *ctx);
   void AddSendMessage(const google::protobuf::Message &message);
   void AddRecvMessage(google::protobuf::Message *message);
   void AddClientSendClose();
   void AddClientRecvStatus(Status *status);
-  void AddServerSendStatus(std::multimap<grpc::string, grpc::string> *metadata, const Status& status);
+  void AddServerSendStatus(std::multimap<grpc::string, grpc::string> *metadata,
+                           const Status &status);
 
   // INTERNAL API:
 
@@ -79,20 +81,21 @@ class CallOpBuffer final : public CompletionQueueTag {
 
  private:
   void *return_tag_ = nullptr;
+  bool send_initial_metadata_ = false;
   size_t initial_metadata_count_ = 0;
-  grpc_metadata* initial_metadata_ = nullptr;
-  const google::protobuf::Message* send_message_ = nullptr;
-  grpc_byte_buffer* send_message_buf_ = nullptr;
-  google::protobuf::Message* recv_message_ = nullptr;
-  grpc_byte_buffer* recv_message_buf_ = nullptr;
+  grpc_metadata *initial_metadata_ = nullptr;
+  const google::protobuf::Message *send_message_ = nullptr;
+  grpc_byte_buffer *send_message_buf_ = nullptr;
+  google::protobuf::Message *recv_message_ = nullptr;
+  grpc_byte_buffer *recv_message_buf_ = nullptr;
   bool client_send_close_ = false;
-  Status* recv_status_ = nullptr;
+  Status *recv_status_ = nullptr;
   grpc_status_code status_code_ = GRPC_STATUS_OK;
-  char* status_details_ = nullptr;
+  char *status_details_ = nullptr;
   size_t status_details_capacity_ = 0;
-  Status* send_status_ = nullptr;
+  Status *send_status_ = nullptr;
   size_t trailing_metadata_count_ = 0;
-  grpc_metadata* trailing_metadata_ = nullptr;
+  grpc_metadata *trailing_metadata_ = nullptr;
 };
 
 class CCallDeleter {
diff --git a/src/cpp/client/client_context.cc b/src/cpp/client/client_context.cc
index 7bda2d07c317a03595d20eb309667a6d48fb21c4..5c2772f5dfba2a1ee18f8dad2abcb547d0f9f72d 100644
--- a/src/cpp/client/client_context.cc
+++ b/src/cpp/client/client_context.cc
@@ -72,7 +72,7 @@ system_clock::time_point ClientContext::absolute_deadline() {
 
 void ClientContext::AddMetadata(const grpc::string &meta_key,
                                 const grpc::string &meta_value) {
-  return;
+  metadata_.insert(std::make_pair(meta_key, meta_value));
 }
 
 void ClientContext::StartCancel() {}
diff --git a/src/cpp/client/client_unary_call.cc b/src/cpp/client/client_unary_call.cc
index 8598592068563a023d40f03425aad809a36a23bd..73be3cff8c132910fec0d2f25cc820b74f943da4 100644
--- a/src/cpp/client/client_unary_call.cc
+++ b/src/cpp/client/client_unary_call.cc
@@ -48,6 +48,7 @@ Status BlockingUnaryCall(ChannelInterface *channel, const RpcMethod &method,
   Call call(channel->CreateCall(method, context, &cq));
   CallOpBuffer buf;
   Status status;
+  buf.AddSendInitialMetadata(context);
   buf.AddSendMessage(request);
   buf.AddRecvMessage(result);
   buf.AddClientSendClose();
diff --git a/src/cpp/common/call.cc b/src/cpp/common/call.cc
index b2cd55fe2459915dbb08e18be6ae21b6dfc91709..f97240d067c4d0d4d67d25136994ce7410e106c5 100644
--- a/src/cpp/common/call.cc
+++ b/src/cpp/common/call.cc
@@ -31,9 +31,10 @@
  *
  */
 
-#include <include/grpc/support/alloc.h>
-#include <include/grpc++/impl/call.h>
-#include <include/grpc++/channel_interface.h>
+#include <grpc/support/alloc.h>
+#include <grpc++/impl/call.h>
+#include <grpc++/client_context.h>
+#include <grpc++/channel_interface.h>
 
 #include "src/cpp/proto/proto_utils.h"
 
@@ -41,10 +42,9 @@ namespace grpc {
 
 void CallOpBuffer::Reset(void* next_return_tag) {
   return_tag_ = next_return_tag;
+  send_initial_metadata_ = false;
   initial_metadata_count_ = 0;
-  if (initial_metadata_) {
-    gpr_free(initial_metadata_);
-  }
+  gpr_free(initial_metadata_);
   send_message_ = nullptr;
   if (send_message_buf_) {
     grpc_byte_buffer_destroy(send_message_buf_);
@@ -87,10 +87,15 @@ grpc_metadata* FillMetadata(
 
 void CallOpBuffer::AddSendInitialMetadata(
     std::multimap<grpc::string, grpc::string>* metadata) {
+  send_initial_metadata_ = true;
   initial_metadata_count_ = metadata->size();
   initial_metadata_ = FillMetadata(metadata);
 }
 
+void CallOpBuffer::AddSendInitialMetadata(ClientContext *ctx) {
+  AddSendInitialMetadata(&ctx->metadata_);
+}
+
 void CallOpBuffer::AddSendMessage(const google::protobuf::Message& message) {
   send_message_ = &message;
 }
@@ -114,7 +119,7 @@ void CallOpBuffer::AddServerSendStatus(std::multimap<grpc::string, grpc::string>
 
 void CallOpBuffer::FillOps(grpc_op *ops, size_t *nops) {
   *nops = 0;
-  if (initial_metadata_count_) {
+  if (send_initial_metadata_) {
     ops[*nops].op = GRPC_OP_SEND_INITIAL_METADATA;
     ops[*nops].data.send_initial_metadata.count = initial_metadata_count_;
     ops[*nops].data.send_initial_metadata.metadata = initial_metadata_;