diff --git a/pkg/sbi/grpc/connection.go b/pkg/sbi/grpc/connection.go
new file mode 100644
index 0000000..3b65c29
--- /dev/null
+++ b/pkg/sbi/grpc/connection.go
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Package grpc holds utils for grpc client implementation
+package grpc
+
+import (
+	"context"
+
+	"github.com/opencord/device-management-interface/go/dmi"
+	"github.com/opencord/opendevice-manager/pkg/config"
+	"github.com/opencord/voltha-lib-go/v4/pkg/log"
+	"google.golang.org/grpc/credentials"
+
+	g "google.golang.org/grpc"
+)
+
+// logger represents the log object
+var logger log.CLogger
+
+// init function for the package
+func init() {
+	logger = config.Initlog()
+}
+
+// Client holds the parameters for grpc
+type Client struct {
+	uri             string
+	conn            *g.ClientConn
+	hwMgmtSvcClient dmi.NativeHWManagementServiceClient
+}
+
+// NewClient returns a new Grpc Client
+func NewClient(uri string) *Client {
+	c := new(Client)
+	c.uri = uri
+	return c
+}
+
+func (c *Client) getDialOpts(ctx context.Context) []g.DialOption {
+
+	coreFlags := config.NewCoreFlags()
+	var opts []g.DialOption
+
+	if coreFlags.SecureConnection {
+		logger.Info(ctx, "Trying-to-establish-secure-connection")
+
+		creds, err := credentials.NewClientTLSFromFile(coreFlags.CertsPath.RootCaCrt, "")
+		if err != nil {
+			logger.Fatalf(ctx, "could-not-process-the-credentials", log.Fields{"err": err})
+		}
+
+		err = creds.OverrideServerName(coreFlags.GrpcHostName)
+		if err != nil {
+			logger.Fatalf(ctx, "Overriding-server-name-failed-at-getDialOpts()", log.Fields{"err": err})
+		}
+
+		opts = append(opts, g.WithTransportCredentials(creds))
+	} else {
+		logger.Info(ctx, "Trying-to-establish-insecure-connection")
+		opts = append(opts, g.WithInsecure())
+	}
+
+	opts = append(opts, g.WithTimeout(coreFlags.GrpcRetryInterval))
+	backoffConfig := g.BackoffConfig{MaxDelay: coreFlags.GrpcBackoffMaxDelay}
+	opts = append(opts, g.WithBackoffConfig(backoffConfig))
+
+	return opts
+}
+
+// Connect will establish a connection
+func (c *Client) Connect(ctx context.Context) error {
+	logger.Info(ctx, "Invoked-connectGrpcServer")
+	// log.Info("Invoked-connectGrpcServer", log.Opts{"peer-ID": peerID})
+	opts := c.getDialOpts(ctx)
+	// Establishing the server connection
+	conn, err := g.Dial(c.uri, opts...)
+	if err != nil {
+		logger.Error(ctx, "Grpc-client-connection-failed", log.Fields{"error": err})
+		return err
+	}
+	c.conn = conn
+	logger.Info(ctx, "Connection-established", log.Fields{"conn": conn})
+	// Constructing a client object
+	c.hwMgmtSvcClient = dmi.NewNativeHWManagementServiceClient(conn)
+	return nil
+}
+
+// Disconnect will remove the connection
+func (c *Client) Disconnect(ctx context.Context) error {
+	logger.Infow(ctx, "Invoked-Disconnect", log.Fields{"client": c})
+	return c.conn.Close()
+}
diff --git a/pkg/sbi/grpc/hw_mgmt_svc.go b/pkg/sbi/grpc/hw_mgmt_svc.go
new file mode 100644
index 0000000..f2bd64a
--- /dev/null
+++ b/pkg/sbi/grpc/hw_mgmt_svc.go
@@ -0,0 +1,349 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Package grpc holds utils for grpc Client implementation
+package grpc
+
+import (
+	"context"
+	"errors"
+	"io"
+
+	"github.com/opencord/device-management-interface/go/dmi"
+	"github.com/opencord/voltha-lib-go/v4/pkg/log"
+
+	copy "github.com/jinzhu/copier"
+	dev "github.com/opencord/opendevice-manager/pkg/models/device"
+	hw "github.com/opencord/opendevice-manager/pkg/models/hwcomponents"
+)
+
+// StartManagingDevice is the adapter implementation for start managing device in grpc adapter layer
+func (c *Client) StartManagingDevice(ctx context.Context, devRec *dev.DeviceRecord, req *dmi.ModifiableComponent, streamResp dmi.NativeHWManagementService_StartManagingDeviceServer) (error, bool) {
+
+	var connMade bool
+
+	resp := new(dmi.StartManagingDeviceResponse)
+	resp.Status = dmi.Status_ERROR_STATUS
+	resp.Reason = dmi.StartManagingDeviceResponse_INTERNAL_ERROR
+
+	logger.Info(ctx, "Invoked-StartManagingDevice-at-grpc-adapter", log.Fields{"req": req})
+
+	stream, err := c.hwMgmtSvcClient.StartManagingDevice(ctx, req)
+
+	if err != nil {
+		logger.Error(ctx, "error-at-StartManagingDevice")
+		resp.ReasonDetail = err.Error()
+		streamResp.Send(resp)
+		return errors.New("RPC Failed for StartManagingDevice"), connMade
+	}
+
+	for {
+
+		respFromDev, err := stream.Recv()
+
+		if err == io.EOF {
+			logger.Info(ctx, "Exiting-StartManagingDevice-on-connection-break-from-grpc-server", log.Fields{"req": req, "error": err})
+			break
+		}
+
+		if err != nil {
+			logger.Error(ctx, "Failed-at-StartManagingDevice-while-receiving-server-response", log.Fields{"error": err, "req": req})
+			return err, connMade
+		}
+
+		if respFromDev.Status == dmi.Status_OK_STATUS {
+			connMade = true
+			devRec.Uuid = respFromDev.DeviceUuid.Uuid
+			// Store in DB
+			devRec.DBAddByName(ctx)
+			devRec.DBAddUuidLookup(ctx)
+			logger.Infow(ctx, "received-success-response-from-dm-agent-for-StartManagingDevice-req", log.Fields{"req": req, "resp": respFromDev})
+		} else if respFromDev.Status == dmi.Status_ERROR_STATUS || err != nil {
+			logger.Errorw(ctx, "received-failed-response-from-dm-agent-for-StartManagingDevice-req", log.Fields{"req": req, "resp": respFromDev})
+			if err == nil {
+				err = errors.New(respFromDev.ReasonDetail)
+			}
+			streamResp.Send(respFromDev)
+			return err, connMade
+		}
+
+		streamResp.Send(respFromDev)
+	}
+
+	return nil, connMade
+
+}
+
+// StopManagingDevice is the adapter implementation for stop managing device in grpc adapter layer
+func (c *Client) StopManagingDevice(ctx context.Context, devRec *dev.DeviceRecord, req *dmi.StopManagingDeviceRequest) (*dmi.StopManagingDeviceResponse, error) {
+
+	logger.Info(ctx, "Invoked-StopManagingDevice-at-grpc-adapter", log.Fields{"req": req})
+
+	return c.hwMgmtSvcClient.StopManagingDevice(ctx, req)
+
+}
+
+// SetLoggingEndpoint is the adapter implementation for set the location to which logs need to be shipped in grpc adapter layer
+func (c *Client) SetLoggingEndpoint(ctx context.Context, devRec *dev.DeviceRecord, req *dmi.SetLoggingEndpointRequest) (*dmi.SetRemoteEndpointResponse, error) {
+	logger.Info(ctx, "Invoked-SetLoggingEndpoint", log.Fields{"req": req})
+
+	resp, err := c.hwMgmtSvcClient.SetLoggingEndpoint(ctx, req)
+	if err != nil {
+		logger.Error(ctx, "error-at-SetLoggingEndpoint")
+		return resp, err
+	}
+	err = errors.New(resp.ReasonDetail)
+
+	if resp.Status == dmi.Status_OK_STATUS {
+		devRec.Logging.EndPoint = req.LoggingEndpoint
+		devRec.Logging.Protocol = req.LoggingProtocol
+		// Store in DB
+		devRec.DBAddByName(ctx)
+		logger.Infow(ctx, "received-success-response-from-dm-agent-for-SetLoggingEndpoint-req", log.Fields{"req": req, "resp": resp})
+	} else {
+		logger.Errorw(ctx, "received-failed-response-from-dm-agent-for-SetLoggingEndpoint-req", log.Fields{"req": req, "resp": resp})
+	}
+	return resp, err
+}
+
+// GetLoggingEndpoint is the adapter implementation for get the location to which logs need to be shipped in grpc adapter layer
+func (c *Client) GetLoggingEndpoint(ctx context.Context, devRec *dev.DeviceRecord, req *dmi.HardwareID) (*dmi.GetLoggingEndpointResponse, error) {
+	logger.Info(ctx, "Invoked-GetLoggingEndpoint", log.Fields{"req": req})
+
+	resp, err := c.hwMgmtSvcClient.GetLoggingEndpoint(ctx, req)
+	if err != nil {
+		logger.Error(ctx, "error-at-GetLoggingEndpoint")
+		return resp, err
+	}
+	err = errors.New(resp.ReasonDetail)
+
+	if resp.Status == dmi.Status_OK_STATUS {
+		devRec.Logging.EndPoint = resp.LoggingEndpoint
+		devRec.Logging.Protocol = resp.LoggingProtocol
+		// Store in DB
+		devRec.DBAddByName(ctx)
+		logger.Infow(ctx, "received-success-response-from-dm-agent-for-GetLoggingEndpoint-req", log.Fields{"req": req, "resp": resp})
+	} else {
+		logger.Errorw(ctx, "received-failed-response-from-dm-agent-for-GetLoggingEndpoint-req", log.Fields{"req": req, "resp": resp})
+	}
+	return resp, err
+}
+
+// GetPhysicalInventory is the adapter implementation for reading physical inventories in grpc adapter layer
+func (c *Client) GetPhysicalInventory(ctx context.Context, devRec *dev.DeviceRecord, req *dmi.PhysicalInventoryRequest, streamResp dmi.NativeHWManagementService_GetPhysicalInventoryServer) error {
+
+	logger.Info(ctx, "Invoked-GetPhysicalInventory-at-grpc-adapter", log.Fields{"req": req})
+
+	resp := new(dmi.PhysicalInventoryResponse)
+	resp.Status = dmi.Status_ERROR_STATUS
+	resp.Reason = dmi.PhysicalInventoryResponse_INTERNAL_ERROR
+
+	stream, err := c.hwMgmtSvcClient.GetPhysicalInventory(ctx, req)
+
+	if err != nil {
+		logger.Error(ctx, "error-at-GetPhysicalInventory", log.Fields{"error": err})
+		resp.ReasonDetail = err.Error()
+		streamResp.Send(resp)
+		return err
+	}
+
+	for {
+
+		respFromDev, err := stream.Recv()
+
+		if err == io.EOF {
+			logger.Info(ctx, "Exiting-GetPhysicalInventory-on-connection-break-from-grpc-server", log.Fields{"req": req, "error": err})
+			break
+		}
+
+		if err != nil {
+			logger.Error(ctx, "Failed-at-GetPhysicalInventory-while-receiving-server-response", log.Fields{"error": err, "request": req})
+			return err
+		}
+
+		if respFromDev.Status == dmi.Status_OK_STATUS {
+
+			// Store in DB
+			devRec.DBSaveHwInfo(ctx, respFromDev.Inventory)
+			nameToUuidMap := make(map[string]string)
+			hw.DBSaveHwCompsFromPhysicalInventory(ctx, devRec.Uuid, nameToUuidMap, respFromDev.Inventory.Root.Children)
+			hw.DBAddNameToUuidlookup(ctx, devRec.Uuid, nameToUuidMap)
+			logger.Infow(ctx, "received-success-response-from-dm-agent-for-GetPhysicalInventory-req", log.Fields{"req": req, "resp": respFromDev})
+
+		} else if respFromDev.Status == dmi.Status_ERROR_STATUS || err != nil {
+
+			logger.Errorw(ctx, "received-failed-response-from-dm-agent-for-GetPhysicalInventory-req", log.Fields{"req": req, "resp": respFromDev})
+			if err == nil {
+				err = errors.New(respFromDev.ReasonDetail)
+			}
+			streamResp.Send(respFromDev)
+			return err
+
+		}
+
+		streamResp.Send(respFromDev)
+	}
+
+	return nil
+}
+
+// GetLoggableEntities is the adapter implementation for reading physical inventories in grpc adapter layer
+func (c *Client) GetLoggableEntities(ctx context.Context, devRec *dev.DeviceRecord, req *dmi.GetLoggableEntitiesRequest) (*dmi.GetLogLevelResponse, error) {
+
+	logger.Info(ctx, "Invoked-GetLoggableEntities-at-grpc-adapter", log.Fields{"req": req})
+
+	resp, err := c.hwMgmtSvcClient.GetLoggableEntities(ctx, req)
+
+	if err != nil {
+		logger.Error(ctx, "Failed-at-GetLoggableEntities-while-receiving-server-response", log.Fields{"error": err, "request": req})
+		return resp, err
+	}
+	// update the db if get log response is success from device
+	if resp.Status == dmi.Status_OK_STATUS {
+		devRec.SaveLoggableEntities(ctx, resp.LogLevels)
+		devRec.DBAddByName(ctx)
+	}
+
+	return resp, err
+}
+
+// SetLogLevel is the adapter implementation for reading physical inventories in grpc adapter layer
+func (c *Client) SetLogLevel(ctx context.Context, devRec *dev.DeviceRecord, req *dmi.SetLogLevelRequest) (*dmi.SetLogLevelResponse, error) {
+
+	logger.Info(ctx, "Invoked-SetLogLevel-at-grpc-adapter", log.Fields{"req": req})
+
+	resp, err := c.hwMgmtSvcClient.SetLogLevel(ctx, req)
+
+	if err != nil {
+		logger.Error(ctx, "Failed-at-SetLogLevel-while-receiving-server-response", log.Fields{"error": err, "request": req})
+		return resp, err
+	}
+	// update the db if setting log response is success from device
+	if resp.Status == dmi.Status_OK_STATUS {
+		devRec.SaveLoggableEntities(ctx, req.Loglevels)
+		devRec.DBAddByName(ctx)
+	}
+
+	return resp, err
+}
+
+// GetLogLevel is the adapter implementation for reading physical inventories in grpc adapter layer
+func (c *Client) GetLogLevel(ctx context.Context, devRec *dev.DeviceRecord, req *dmi.GetLogLevelRequest) (*dmi.GetLogLevelResponse, error) {
+
+	logger.Info(ctx, "Invoked-GetLogLevel-at-grpc-adapter", log.Fields{"req": req})
+
+	resp, err := c.hwMgmtSvcClient.GetLogLevel(ctx, req)
+
+	if err != nil {
+		logger.Error(ctx, "Failed-at-GetLogLevel-while-receiving-server-response", log.Fields{"error": err, "request": req})
+		return resp, err
+	}
+
+	// update the db if get log response is success from device
+	if resp.Status == dmi.Status_OK_STATUS {
+		devRec.SaveLoggableEntities(ctx, resp.LogLevels)
+		devRec.DBAddByName(ctx)
+	}
+
+	return resp, err
+}
+
+// GetHWComponentInfo is the adapter implementation for get the details of a particular HW component
+func (c *Client) GetHWComponentInfo(ctx context.Context, deviceUuid string, hwCompRec *hw.HwCompRecord, req *dmi.HWComponentInfoGetRequest, streamResp dmi.NativeHWManagementService_GetHWComponentInfoServer) error {
+
+	logger.Info(ctx, "Invoked-GetHWComponentInfo-at-grpc-adapter", log.Fields{"req": req})
+
+	resp := new(dmi.HWComponentInfoGetResponse)
+	resp.Status = dmi.Status_ERROR_STATUS
+	resp.Reason = dmi.HWComponentInfoGetResponse_INTERNAL_ERROR
+
+	stream, err := c.hwMgmtSvcClient.GetHWComponentInfo(ctx, req)
+
+	if err != nil {
+		logger.Error(ctx, "error-at-GetHWComponentInfo", log.Fields{"error": err})
+		resp.ReasonDetail = err.Error()
+		streamResp.Send(resp)
+		return err
+	}
+
+	for {
+
+		respFromDev, err := stream.Recv()
+
+		if err == io.EOF {
+			logger.Info(ctx, "Exiting-GetHWComponentInfo-on-connection-break-from-grpc-server", log.Fields{"req": req, "error": err})
+			break
+		}
+
+		if err != nil {
+			logger.Error(ctx, "Failed-at-GetHWComponentInfo-while-receiving-server-response", log.Fields{"error": err, "request": req})
+			return err
+		}
+
+		if respFromDev.Status == dmi.Status_OK_STATUS {
+			if hwCompRec.State == nil {
+				hwCompRec.State = new(dmi.ComponentState)
+			}
+			err = copy.Copy(&hwCompRec, &respFromDev.Component)
+			if err != nil {
+				logger.Error(ctx, "Failed-at-GetHWComponentInfo-copy-failed", log.Fields{"error": err, "resp": respFromDev.Component})
+			}
+			if respFromDev.Component.State != nil {
+				hwCompRec.State.AdminState = respFromDev.Component.State.AdminState
+			}
+			// Store in DB
+			hwCompRec.DBAddByUuid(ctx, deviceUuid)
+			logger.Infow(ctx, "received-success-response-from-dm-agent-for-GetHWComponentInfo-req", log.Fields{"req": req, "resp": respFromDev})
+		} else if respFromDev.Status == dmi.Status_ERROR_STATUS || err != nil {
+			logger.Errorw(ctx, "received-failed-response-from-dm-agent-for-GetHWComponentInfo-req", log.Fields{"req": req, "resp": respFromDev})
+			if err == nil {
+				err = errors.New(respFromDev.ReasonDetail)
+			}
+			streamResp.Send(respFromDev)
+			return err
+		}
+
+		streamResp.Send(respFromDev)
+	}
+
+	return nil
+}
+
+// SetHWComponentInfo method is the grpc adapter implementation for setting hw component info on device
+func (c *Client) SetHWComponentInfo(ctx context.Context, deviceUuid string, hwCompRec *hw.HwCompRecord, req *dmi.HWComponentInfoSetRequest) (*dmi.HWComponentInfoSetResponse, error) {
+	logger.Info(ctx, "Invoked-SetHWComponentInfo", log.Fields{"req": req})
+
+	resp, err := c.hwMgmtSvcClient.SetHWComponentInfo(ctx, req)
+
+	if err != nil {
+		logger.Error(ctx, "error-at-SetHWComponentInfo", log.Fields{"req": req, "error": err})
+		return resp, err
+	}
+
+	if resp.Status == dmi.Status_OK_STATUS {
+		hwCompRec.State = new(dmi.ComponentState)
+		err = copy.Copy(&hwCompRec, &req.Changes)
+		hwCompRec.State.AdminState = req.Changes.AdminState
+		// Store in DB
+		hwCompRec.DBAddByUuid(ctx, deviceUuid)
+		logger.Infow(ctx, "received-success-response-from-dm-agent-for-SetHWComponentInfo-req", log.Fields{"req": req, "resp": resp})
+	} else {
+		logger.Errorw(ctx, "received-failed-response-from-dm-agent-for-SetHWComponentInfo-req", log.Fields{"req": req, "resp": resp})
+		err = errors.New(resp.ReasonDetail)
+	}
+
+	return resp, err
+}
