diff --git a/pkg/nbi/hw_mgmt_svc_api.go b/pkg/nbi/hw_mgmt_svc_api.go
new file mode 100644
index 0000000..0bfd82f
--- /dev/null
+++ b/pkg/nbi/hw_mgmt_svc_api.go
@@ -0,0 +1,388 @@
+/*
+ * 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 nbi holds rpc server apis implemented
+package nbi
+
+import (
+	"context"
+	"errors"
+	"fmt"
+
+	"github.com/jinzhu/copier"
+	"github.com/opencord/device-management-interface/go/dmi"
+	"github.com/opencord/opendevice-manager/pkg/config"
+	"github.com/opencord/voltha-lib-go/v4/pkg/log"
+
+	dev "github.com/opencord/opendevice-manager/pkg/models/device"
+	hw "github.com/opencord/opendevice-manager/pkg/models/hwcomponents"
+
+	empty "github.com/golang/protobuf/ptypes/empty"
+)
+
+// StartManagingDevice refers to the RPC method invoked for start Managing Device.
+// Initializes context for a device and sets up required states
+func (c *NativeHwManagementService) StartManagingDevice(req *dmi.ModifiableComponent, streamResp dmi.NativeHWManagementService_StartManagingDeviceServer) error {
+	ctx := config.GetNewContextFromGlobalContxt("StartManagingDevice")
+
+	logger.Infow(ctx, "StartManagingDevice-invoked-on-grpc-server", log.Fields{"req": req})
+	defer logger.Infow(ctx, "StartManagingDevice-on-grpc-server-completed", log.Fields{"req": req})
+
+	if errorResp, ok := validateStartManagingDeviceReq(ctx, req); !ok {
+		streamResp.Send(errorResp)
+		return errors.New("failed at validateStartManagingDeviceReq")
+	}
+
+	devRec, err := dev.NewDeviceRecord(ctx, req)
+
+	if err != nil {
+		streamResp.Send(errRespStartManagingDevice(ctx, req, dmi.StartManagingDeviceResponse_INVALID_PARAMS, err))
+		return err
+	}
+
+	adapter, err := connections.getConnection(ctx, devRec)
+
+	if adapter == nil {
+		streamResp.Send(errRespStartManagingDevice(ctx, req, dmi.StartManagingDeviceResponse_INVALID_PARAMS, err))
+		return err
+	}
+
+	devRec.DBAddByName(ctx)
+
+	err, connMade := adapter.StartManagingDevice(ctx, devRec, req, streamResp)
+
+	if !connMade {
+		devRec.DBDelRecord(ctx)
+		adapter.Disconnect(ctx)
+		connections.delConn(ctx, devRec.Name)
+		streamResp.Send(errRespStartManagingDevice(ctx, req, dmi.StartManagingDeviceResponse_UNDEFINED_REASON, err))
+	}
+
+	return err
+}
+
+// StopManagingDevice - Stops management of a device and clean up any context and caches for that device
+// This rpc can be called at any time, even before the StartManagingDevice operation
+// has completed, and should be able to cleanup.
+func (c *NativeHwManagementService) StopManagingDevice(ctx context.Context, req *dmi.StopManagingDeviceRequest) (*dmi.StopManagingDeviceResponse, error) {
+
+	var devRec *dev.DeviceRecord
+	resp := new(dmi.StopManagingDeviceResponse)
+	var err error
+
+	ctx = config.GetNewContextFromContxt(ctx, "StopManagingDevice")
+
+	logger.Infow(ctx, "StopManagingDevice-invoked-on-grpc-server", log.Fields{"req": req})
+	defer logger.Infow(ctx, "StopManagingDevice-on-grpc-server-completed", log.Fields{"req": req})
+
+	if recTmp, err := dev.DBGetByName(ctx, req.Name); recTmp == nil {
+		return errRespStopManagingDevice(ctx, req, dmi.StopManagingDeviceResponse_UNKNOWN_DEVICE, err), err
+	} else {
+		devRec = recTmp
+	}
+
+	defer devRec.DBDelRecord(ctx)
+	defer hw.DBDelAllHwComponents(ctx, devRec.Uuid)
+
+	adapter, err := connections.getConnection(ctx, devRec)
+
+	if adapter != nil {
+		resp, err = adapter.StopManagingDevice(ctx, devRec, req)
+		adapter.Disconnect(ctx)
+		connections.delConn(ctx, devRec.Name)
+	}
+
+	if err != nil {
+		logger.Errorw(ctx, "Errors-at-StopManagingDevice", log.Fields{"req": req, "error": err})
+	}
+
+	return resp, err
+}
+
+// GetManagedDevices - Returns an object containing a list of devices managed by this entity
+func (c *NativeHwManagementService) GetManagedDevices(ctx context.Context, req *empty.Empty) (*dmi.ManagedDevicesResponse, error) {
+	ctx = config.GetNewContextFromContxt(ctx, "GetManagedDevices")
+	resp := new(dmi.ManagedDevicesResponse)
+
+	logger.Infow(ctx, "GetManagedDevices-invoked-on-grpc-server", log.Fields{"req": req})
+	defer logger.Infow(ctx, "GetManagedDevices-on-grpc-server-completed", log.Fields{"req": req})
+
+	listDevRecs, err := dev.DBGetAll(ctx)
+	for _, devRec := range listDevRecs {
+		modComp := new(dmi.ModifiableComponent)
+		err2 := copier.Copy(&modComp, &devRec)
+		if err2 != nil {
+			logger.Errorw(ctx, "Copy-failed-at-GetManagedDevices", log.Fields{"req": req, "rec": devRec, "error": err})
+		} else {
+			modComp.Uri.Uri = devRec.Uri
+			resp.Devices = append(resp.Devices, modComp)
+		}
+	}
+	logger.Infow(ctx, "GetManagedDevices-completed", log.Fields{"req": req, "resp": resp, "error": err})
+	return resp, err
+}
+
+// GetPhysicalInventory - Place Holder for implementation in future
+func (c *NativeHwManagementService) GetPhysicalInventory(req *dmi.PhysicalInventoryRequest, streamResp dmi.NativeHWManagementService_GetPhysicalInventoryServer) error {
+
+	ctx := config.GetNewContextFromGlobalContxt("GetPhysicalInventory")
+
+	logger.Infow(ctx, "GetPhysicalInventory-invoked-on-grpc-server", log.Fields{"req": req})
+	defer logger.Infow(ctx, "GetPhysicalInventory-on-grpc-server-completed", log.Fields{"req": req})
+
+	var devRec *dev.DeviceRecord
+
+	if recTmp, err := dev.DBGetByUuid(ctx, req.DeviceUuid.Uuid); recTmp == nil {
+		streamResp.Send(errRespGetPhysicatInventory(ctx, req, dmi.PhysicalInventoryResponse_UNKNOWN_DEVICE, err))
+		return err
+	} else {
+		devRec = recTmp
+	}
+
+	adapter, err := connections.getConnection(ctx, devRec)
+	if adapter == nil {
+		streamResp.Send(errRespGetPhysicatInventory(ctx, req, dmi.PhysicalInventoryResponse_DEVICE_UNREACHABLE, err))
+		return err
+	}
+
+	err = adapter.GetPhysicalInventory(ctx, devRec, req, streamResp)
+
+	if err != nil {
+		logger.Errorw(ctx, "Errors-at-GetPhysicalInventory", log.Fields{"req": req, "error": err})
+	}
+
+	return err
+}
+
+// GetHWComponentInfo - refers to the RPC method invoked for get the details of a particular HW component
+func (c *NativeHwManagementService) GetHWComponentInfo(req *dmi.HWComponentInfoGetRequest, streamResp dmi.NativeHWManagementService_GetHWComponentInfoServer) error {
+	ctx := config.GetNewContextFromGlobalContxt("GetHWComponentInfo")
+
+	logger.Infow(ctx, "GetHWComponentInfo-invoked-on-grpc-server", log.Fields{"req": req})
+	defer logger.Infow(ctx, "GetHWComponentInfo-on-grpc-server-completed", log.Fields{"req": req})
+
+	devRec, err := dev.DBGetByUuid(ctx, req.DeviceUuid.Uuid)
+	if devRec == nil {
+		streamResp.Send(errRespGetHWComponentInfo(ctx, req, dmi.HWComponentInfoGetResponse_UNKNOWN_DEVICE, err))
+		return err
+	}
+
+	hwCompRec, err := hw.DBGetRecByUuid(ctx, req.DeviceUuid.Uuid, req.ComponentUuid.Uuid)
+	if hwCompRec == nil {
+		streamResp.Send(errRespGetHWComponentInfo(ctx, req, dmi.HWComponentInfoGetResponse_UNKNOWN_DEVICE, err))
+		return err
+	}
+
+	adapter, err := connections.getConnection(ctx, devRec)
+	if adapter == nil {
+		streamResp.Send(errRespGetHWComponentInfo(ctx, req, dmi.HWComponentInfoGetResponse_DEVICE_UNREACHABLE, err))
+		return err
+	}
+
+	err = adapter.GetHWComponentInfo(ctx, devRec.Uuid, hwCompRec, req, streamResp)
+	if err != nil {
+		logger.Errorw(ctx, "Errors-at-GetHWComponentInfo", log.Fields{"req": req, "error": err})
+	}
+	return err
+}
+
+// SetHWComponentInfo is the nb api exposed for receiving SetHWComponentInfo from NEM
+func (c *NativeHwManagementService) SetHWComponentInfo(ctx context.Context, req *dmi.HWComponentInfoSetRequest) (*dmi.HWComponentInfoSetResponse, error) {
+	ctx = config.GetNewContextFromContxt(ctx, "SetHWComponentInfo")
+
+	logger.Infow(ctx, "SetHWComponentInfo-invoked-on-grpc-server", log.Fields{"req": req})
+	defer logger.Infow(ctx, "SetHWComponentInfo-on-grpc-server-completed", log.Fields{"req": req})
+
+	var devRec *dev.DeviceRecord
+	var hwCompRec *hw.HwCompRecord
+	var err error
+
+	if devRec, err = dev.DBGetByUuid(ctx, req.DeviceUuid.Uuid); devRec == nil {
+		return errRespSetHWComponentInfo(ctx, req, dmi.HWComponentInfoSetResponse_UNKNOWN_DEVICE, err), err
+	}
+
+	if hwCompRec, err = hw.DBGetRecByUuid(ctx, req.DeviceUuid.Uuid, req.ComponentUuid.Uuid); hwCompRec == nil {
+		return errRespSetHWComponentInfo(ctx, req, dmi.HWComponentInfoSetResponse_UNKNOWN_DEVICE, err), err
+	}
+
+	adapter, err := connections.getConnection(ctx, devRec)
+	if adapter == nil {
+		return errRespSetHWComponentInfo(ctx, req, dmi.HWComponentInfoSetResponse_DEVICE_UNREACHABLE, err), err
+	}
+
+	resp, err := adapter.SetHWComponentInfo(ctx, devRec.Uuid, hwCompRec, req)
+
+	if err != nil {
+		logger.Errorw(ctx, "Errors-at-SetHWComponentInfo", log.Fields{"req": req, "error": err})
+	}
+
+	return resp, err
+}
+
+// SetLoggingEndpoint - refers to the RPC method invoked for set the location to which logs need to be shipped
+func (c *NativeHwManagementService) SetLoggingEndpoint(ctx context.Context, req *dmi.SetLoggingEndpointRequest) (*dmi.SetRemoteEndpointResponse, error) {
+	ctx = config.GetNewContextFromGlobalContxt("SetLoggingEndpoint")
+
+	logger.Infow(ctx, "SetLoggingEndpoint-invoked-on-grpc-server", log.Fields{"req": req})
+	defer logger.Infow(ctx, "SetLoggingEndpoint-on-grpc-server-completed", log.Fields{"req": req})
+
+	// Check device is there or not by Uuid
+	devRec, err := dev.DBGetByUuid(ctx, req.DeviceUuid.Uuid)
+	if err != nil {
+		return errRespSetLoggingEndpoint(ctx, req, dmi.SetRemoteEndpointResponse_UNKNOWN_DEVICE, err), err
+	}
+
+	adapter, err2 := connections.getConnection(ctx, devRec)
+	if adapter == nil {
+		return errRespSetLoggingEndpoint(ctx, req, dmi.SetRemoteEndpointResponse_DEVICE_UNREACHABLE, err2), err2
+	}
+
+	resp, err := adapter.SetLoggingEndpoint(ctx, devRec, req)
+	if err != nil {
+		logger.Errorw(ctx, "Errors-at-SetLoggingEndpoint", log.Fields{"req": req, "error": err})
+	}
+
+	return resp, err
+}
+
+// GetLoggingEndpoint - refers to the RPC method invoked for get the location to which logs need to be shipped
+func (c *NativeHwManagementService) GetLoggingEndpoint(ctx context.Context, req *dmi.HardwareID) (*dmi.GetLoggingEndpointResponse, error) {
+	ctx = config.GetNewContextFromGlobalContxt("GetLoggingEndpoint")
+
+	logger.Infow(ctx, "GetLoggingEndpoint-invoked-on-grpc-server", log.Fields{"req": req})
+	defer logger.Infow(ctx, "GetLoggingEndpoint-on-grpc-server-completed", log.Fields{"req": req})
+
+	// Check device is there or not by Uuid
+	devRec, err := dev.DBGetByUuid(ctx, req.Uuid.Uuid)
+	if err != nil {
+		return errRespGetLoggingEndpoint(ctx, req, dmi.GetLoggingEndpointResponse_UNKNOWN_DEVICE, err), err
+	}
+
+	adapter, err := connections.getConnection(ctx, devRec)
+	if adapter == nil {
+		return errRespGetLoggingEndpoint(ctx, req, dmi.GetLoggingEndpointResponse_DEVICE_UNREACHABLE, err), err
+	}
+
+	resp, err := adapter.GetLoggingEndpoint(ctx, devRec, req)
+	if err != nil {
+		logger.Errorw(ctx, "Errors-at-GetLoggingEndpoint", log.Fields{"req": req, "error": err})
+	}
+	return resp, err
+}
+
+// SetMsgBusEndpoint - Place Holder for implementation in future
+func (c *NativeHwManagementService) SetMsgBusEndpoint(ctx context.Context, req *dmi.SetMsgBusEndpointRequest) (*dmi.SetRemoteEndpointResponse, error) {
+	errMsg := "SetMsgBusEndpoint not yet implemented"
+	fmt.Println(errMsg)
+	return nil, errors.New(errMsg)
+}
+
+// GetMsgBusEndpoint - Place Holder for implementation in future
+func (c *NativeHwManagementService) GetMsgBusEndpoint(ctx context.Context, req *empty.Empty) (*dmi.GetMsgBusEndpointResponse, error) {
+	errMsg := "GetMsgBusEndpoint not yet implemented"
+	fmt.Println(errMsg)
+	return nil, errors.New(errMsg)
+}
+
+// GetLoggableEntities refers to the grpc northbound interface exposed for getting loggable entities from device
+func (c *NativeHwManagementService) GetLoggableEntities(ctx context.Context, req *dmi.GetLoggableEntitiesRequest) (*dmi.GetLogLevelResponse, error) {
+
+	ctx = config.GetNewContextFromContxt(ctx, "GetLoggableEntities")
+	resp := new(dmi.GetLogLevelResponse)
+	resp.DeviceUuid = req.DeviceUuid
+
+	logger.Infow(ctx, "GetLoggableEntities-invoked-on-grpc-server", log.Fields{"req": req})
+	defer logger.Infow(ctx, "GetLoggableEntities-on-grpc-server-completed", log.Fields{"req": req})
+
+	devRec, err := dev.DBGetByUuid(ctx, req.DeviceUuid.Uuid)
+	if err != nil {
+		return errRespGetLoggableEntities(ctx, req, dmi.GetLogLevelResponse_UNKNOWN_DEVICE, err), err
+	}
+
+	if devRec.Logging.LoggableEntities != nil {
+		resp.Status = dmi.Status_OK_STATUS
+		resp.LogLevels, _ = devRec.GetLoggableEntitiesFromDevRec(ctx, nil)
+		return resp, nil
+	}
+
+	adapter, err := connections.getConnection(ctx, devRec)
+	if adapter == nil {
+		return errRespGetLoggableEntities(ctx, req, dmi.GetLogLevelResponse_DEVICE_UNREACHABLE, err), err
+	}
+
+	return adapter.GetLoggableEntities(ctx, devRec, req)
+}
+
+// SetLogLevel refers to the grpc northbound interface exposed for setting log level for entities
+func (c *NativeHwManagementService) SetLogLevel(ctx context.Context, req *dmi.SetLogLevelRequest) (*dmi.SetLogLevelResponse, error) {
+
+	ctx = config.GetNewContextFromContxt(ctx, "SetLogLevel")
+	resp := new(dmi.SetLogLevelResponse)
+	resp.DeviceUuid = req.DeviceUuid
+
+	logger.Infow(ctx, "SetLogLevel-invoked-on-grpc-server", log.Fields{"req": req})
+	defer logger.Infow(ctx, "SetLogLevel-on-grpc-server-completed", log.Fields{"req": req})
+
+	// validate request
+	if ok, err := isValidSetLogLevel(ctx, req.Loglevels); ok {
+		return errRespSetLogLevel(ctx, req, dmi.SetLogLevelResponse_UNKNOWN_LOG_ENTITY, err), err
+	}
+
+	devRec, err := dev.DBGetByUuid(ctx, req.DeviceUuid.Uuid)
+	if err != nil {
+		return errRespSetLogLevel(ctx, req, dmi.SetLogLevelResponse_UNKNOWN_DEVICE, err), err
+	}
+
+	adapter, err := connections.getConnection(ctx, devRec)
+	if adapter == nil {
+		return errRespSetLogLevel(ctx, req, dmi.SetLogLevelResponse_DEVICE_UNREACHABLE, err), err
+	}
+
+	return adapter.SetLogLevel(ctx, devRec, req)
+}
+
+// GetLogLevel refers to the grpc northbound interface exposed for getting log level of entities
+func (c *NativeHwManagementService) GetLogLevel(ctx context.Context, req *dmi.GetLogLevelRequest) (*dmi.GetLogLevelResponse, error) {
+
+	ctx = config.GetNewContextFromContxt(ctx, "GetLogLevel")
+	resp := new(dmi.GetLogLevelResponse)
+	resp.DeviceUuid = req.DeviceUuid
+
+	logger.Infow(ctx, "GetLogLevel-invoked-on-grpc-server", log.Fields{"req": req})
+	defer logger.Infow(ctx, "GetLogLevel-on-grpc-server-completed", log.Fields{"req": req})
+
+	devRec, err := dev.DBGetByUuid(ctx, req.DeviceUuid.Uuid)
+	if err != nil {
+		return errRespGetLogLevel(ctx, req, dmi.GetLogLevelResponse_UNKNOWN_DEVICE, err), err
+	}
+
+	if devRec.Logging.LoggableEntities != nil {
+
+		if output, ok := devRec.GetLoggableEntitiesFromDevRec(ctx, req.Entities); ok {
+			resp.Status = dmi.Status_OK_STATUS
+			resp.LogLevels = output
+			return resp, nil
+		}
+
+	}
+
+	adapter, err := connections.getConnection(ctx, devRec)
+	if adapter == nil {
+		return errRespGetLogLevel(ctx, req, dmi.GetLogLevelResponse_DEVICE_UNREACHABLE, err), err
+	}
+
+	return adapter.GetLogLevel(ctx, devRec, req)
+}
