diff --git a/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/GrpcDeviceUtils.java b/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/GrpcDeviceUtils.java
new file mode 100644
index 0000000..7045b0c
--- /dev/null
+++ b/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/GrpcDeviceUtils.java
@@ -0,0 +1,381 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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 org.onosproject.incubator.rpc.grpc;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.onlab.packet.ChassisId;
+import org.onosproject.grpc.Device.DeviceType;
+import org.onosproject.grpc.Port.PortType;
+import org.onosproject.net.Annotations;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.Device;
+import org.onosproject.net.MastershipRole;
+import org.onosproject.net.Port;
+import org.onosproject.net.Port.Type;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.SparseAnnotations;
+import org.onosproject.net.device.DefaultDeviceDescription;
+import org.onosproject.net.device.DefaultPortDescription;
+import org.onosproject.net.device.DefaultPortStatistics;
+import org.onosproject.net.device.DeviceDescription;
+import org.onosproject.net.device.PortDescription;
+import org.onosproject.net.device.PortStatistics;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.api.client.repackaged.com.google.common.annotations.Beta;
+
+/**
+ * gRPC message conversion related utilities.
+ */
+@Beta
+public final class GrpcDeviceUtils {
+
+    private static final Logger log = LoggerFactory.getLogger(GrpcDeviceUtils.class);
+
+    /**
+     * Translates gRPC enum MastershipRole to ONOS enum.
+     *
+     * @param role mastership role in gRPC enum
+     * @return equivalent in ONOS enum
+     */
+    public static MastershipRole translate(org.onosproject.grpc.Device.MastershipRole role) {
+        switch (role) {
+        case NONE:
+            return MastershipRole.NONE;
+        case MASTER:
+            return MastershipRole.MASTER;
+        case STANDBY:
+            return MastershipRole.STANDBY;
+        case UNRECOGNIZED:
+            log.warn("Unrecognized MastershipRole gRPC message: {}", role);
+        default:
+            return MastershipRole.NONE;
+        }
+    }
+
+    /**
+     * Translates ONOS enum MastershipRole to gRPC enum.
+     *
+     * @param newRole ONOS' mastership role
+     * @return equivalent in gRPC message enum
+     */
+    public static org.onosproject.grpc.Device.MastershipRole translate(MastershipRole newRole) {
+        switch (newRole) {
+        case MASTER:
+            return org.onosproject.grpc.Device.MastershipRole.MASTER;
+        case STANDBY:
+            return org.onosproject.grpc.Device.MastershipRole.STANDBY;
+        case NONE:
+        default:
+            return org.onosproject.grpc.Device.MastershipRole.NONE;
+        }
+    }
+
+
+    /**
+     * Translates gRPC DeviceDescription to {@link DeviceDescription}.
+     *
+     * @param deviceDescription gRPC message
+     * @return {@link DeviceDescription}
+     */
+    public static DeviceDescription translate(org.onosproject.grpc.Device.DeviceDescription deviceDescription) {
+        URI uri = URI.create(deviceDescription.getDeviceUri());
+        Device.Type type = translate(deviceDescription.getType());
+        String manufacturer = deviceDescription.getManufacturer();
+        String hwVersion = deviceDescription.getHwVersion();
+        String swVersion = deviceDescription.getSwVersion();
+        String serialNumber = deviceDescription.getSerialNumber();
+        ChassisId chassis = new ChassisId(deviceDescription.getChassisId());
+        return new DefaultDeviceDescription(uri, type, manufacturer,
+                                            hwVersion, swVersion, serialNumber,
+                                            chassis,
+                                            asAnnotations(deviceDescription.getAnnotations()));
+    }
+
+    /**
+     * Translates {@link DeviceDescription} to gRPC DeviceDescription message.
+     *
+     * @param deviceDescription {@link DeviceDescription}
+     * @return gRPC DeviceDescription message
+     */
+    public static org.onosproject.grpc.Device.DeviceDescription translate(DeviceDescription deviceDescription) {
+
+        return org.onosproject.grpc.Device.DeviceDescription.newBuilder()
+            .setDeviceUri(deviceDescription.deviceUri().toString())
+            .setType(translate(deviceDescription.type()))
+            .setManufacturer(deviceDescription.manufacturer())
+            .setHwVersion(deviceDescription.hwVersion())
+            .setSwVersion(deviceDescription.swVersion())
+            .setSerialNumber(deviceDescription.serialNumber())
+            .setChassisId(deviceDescription.chassisId().toString())
+            .putAllAnnotations(asMap(deviceDescription.annotations()))
+            .build();
+    }
+
+
+    /**
+     * Translates gRPC DeviceType to {@link Device.Type}.
+     *
+     * @param type      gRPC message
+     * @return  {@link Device.Type}
+     */
+    public static Device.Type translate(org.onosproject.grpc.Device.DeviceType type) {
+        switch (type) {
+        case BALANCER:
+            return Device.Type.BALANCER;
+        case CONTROLLER:
+            return Device.Type.CONTROLLER;
+        case FIBER_SWITCH:
+            return Device.Type.FIBER_SWITCH;
+        case FIREWALL:
+            return Device.Type.FIREWALL;
+        case IDS:
+            return Device.Type.IDS;
+        case IPS:
+            return Device.Type.IPS;
+        case MICROWAVE:
+            return Device.Type.MICROWAVE;
+        case OTHER:
+            return Device.Type.OTHER;
+        case OTN:
+            return Device.Type.OTN;
+        case ROADM:
+            return Device.Type.ROADM;
+        case ROADM_OTN:
+            return Device.Type.ROADM_OTN;
+        case ROUTER:
+            return Device.Type.ROUTER;
+        case SWITCH:
+            return Device.Type.SWITCH;
+        case VIRTUAL:
+            return Device.Type.VIRTUAL;
+
+        case UNRECOGNIZED:
+        default:
+            log.warn("Unexpected DeviceType: {}", type);
+            return Device.Type.OTHER;
+        }
+    }
+
+    /**
+     * Translates {@link Type} to gRPC DeviceType.
+     *
+     * @param type {@link Type}
+     * @return  gRPC message
+     */
+    public static DeviceType translate(Device.Type type) {
+        switch (type) {
+        case BALANCER:
+            return DeviceType.BALANCER;
+        case CONTROLLER:
+            return DeviceType.CONTROLLER;
+        case FIBER_SWITCH:
+            return DeviceType.FIBER_SWITCH;
+        case FIREWALL:
+            return DeviceType.FIREWALL;
+        case IDS:
+            return DeviceType.IDS;
+        case IPS:
+            return DeviceType.IPS;
+        case MICROWAVE:
+            return DeviceType.MICROWAVE;
+        case OTHER:
+            return DeviceType.OTHER;
+        case OTN:
+            return DeviceType.OTN;
+        case ROADM:
+            return DeviceType.ROADM;
+        case ROADM_OTN:
+            return DeviceType.ROADM_OTN;
+        case ROUTER:
+            return DeviceType.ROUTER;
+        case SWITCH:
+            return DeviceType.SWITCH;
+        case VIRTUAL:
+            return DeviceType.VIRTUAL;
+
+        default:
+            log.warn("Unexpected Device.Type: {}", type);
+            return DeviceType.OTHER;
+        }
+    }
+
+    /**
+     * Translates gRPC PortDescription message to {@link PortDescription}.
+     *
+     * @param portDescription gRPC message
+     * @return {@link PortDescription}
+     */
+    public static PortDescription translate(org.onosproject.grpc.Port.PortDescription portDescription) {
+        PortNumber number = PortNumber.fromString(portDescription.getPortNumber());
+        boolean isEnabled = portDescription.getIsEnabled();
+        Port.Type type = translate(portDescription.getType());
+        long portSpeed = portDescription.getPortSpeed();
+        SparseAnnotations annotations = asAnnotations(portDescription.getAnnotations());
+        // TODO How to deal with more specific Port...
+        return new DefaultPortDescription(number, isEnabled, type, portSpeed, annotations);
+    }
+
+    /**
+     * Translates {@link PortDescription} to gRPC PortDescription message.
+     *
+     * @param portDescription {@link PortDescription}
+     * @return gRPC PortDescription message
+     */
+    public static org.onosproject.grpc.Port.PortDescription translate(PortDescription portDescription) {
+        // TODO How to deal with more specific Port...
+        return org.onosproject.grpc.Port.PortDescription.newBuilder()
+                .setPortNumber(portDescription.portNumber().toString())
+                .setIsEnabled(portDescription.isEnabled())
+                .setType(translate(portDescription.type()))
+                .setPortSpeed(portDescription.portSpeed())
+                .putAllAnnotations(asMap(portDescription.annotations()))
+                .build();
+    }
+
+    /**
+     * Translates gRPC PortType to {@link Port.Type}.
+     *
+     * @param type      gRPC message
+     * @return  {@link Port.Type}
+     */
+    public static Port.Type translate(PortType type) {
+        switch (type) {
+        case COPPER:
+            return Type.COPPER;
+        case FIBER:
+            return Type.FIBER;
+        case OCH:
+            return Type.OCH;
+        case ODUCLT:
+            return Type.ODUCLT;
+        case OMS:
+            return Type.OMS;
+        case PACKET:
+            return Type.PACKET;
+        case VIRTUAL:
+            return Type.VIRTUAL;
+
+        case UNRECOGNIZED:
+        default:
+            log.warn("Unexpected PortType: {}", type);
+            return Type.COPPER;
+        }
+    }
+
+    /**
+     * Translates {@link Port.Type} to gRPC PortType.
+     *
+     * @param type      {@link Port.Type}
+     * @return  gRPC message
+     */
+    public static PortType translate(Port.Type type) {
+        switch (type) {
+        case COPPER:
+            return PortType.COPPER;
+        case FIBER:
+            return PortType.FIBER;
+        case OCH:
+            return PortType.OCH;
+        case ODUCLT:
+            return PortType.ODUCLT;
+        case OMS:
+            return PortType.OMS;
+        case PACKET:
+            return PortType.PACKET;
+        case VIRTUAL:
+            return PortType.VIRTUAL;
+
+        default:
+            log.warn("Unexpected Port.Type: {}", type);
+            return PortType.COPPER;
+        }
+    }
+
+    /**
+     * Translates gRPC PortStatistics message to {@link PortStatistics}.
+     *
+     * @param portStatistics gRPC PortStatistics message
+     * @return {@link PortStatistics}
+     */
+    public static PortStatistics translate(org.onosproject.grpc.Port.PortStatistics portStatistics) {
+        // TODO implement adding missing fields
+        return DefaultPortStatistics.builder()
+                .setPort(portStatistics.getPort())
+                .setPacketsReceived(portStatistics.getPacketsReceived())
+                .setPacketsSent(portStatistics.getPacketsSent())
+                .build();
+    }
+
+    /**
+     * Translates {@link PortStatistics} to gRPC PortStatistics message.
+     *
+     * @param portStatistics {@link PortStatistics}
+     * @return gRPC PortStatistics message
+     */
+    public static org.onosproject.grpc.Port.PortStatistics translate(PortStatistics portStatistics) {
+        // TODO implement adding missing fields
+        return org.onosproject.grpc.Port.PortStatistics.newBuilder()
+                .setPort(portStatistics.port())
+                .setPacketsReceived(portStatistics.packetsReceived())
+                .setPacketsSent(portStatistics.packetsSent())
+                .build();
+    }
+
+    // may be this can be moved to Annotation itself or AnnotationsUtils
+    /**
+     * Converts Annotations to Map of Strings.
+     *
+     * @param annotations {@link Annotations}
+     * @return Map of annotation key and values
+     */
+    public static Map<String, String> asMap(Annotations annotations) {
+        if (annotations instanceof DefaultAnnotations) {
+            return ((DefaultAnnotations) annotations).asMap();
+        }
+        Map<String, String> map = new HashMap<>();
+        annotations.keys()
+            .forEach(k -> map.put(k, annotations.value(k)));
+
+        return map;
+    }
+
+    // may be this can be moved to Annotation itself or AnnotationsUtils
+    /**
+     * Converts Map of Strings to {@link SparseAnnotations}.
+     *
+     * @param annotations Map of annotation key and values
+     * @return {@link SparseAnnotations}
+     */
+    public static SparseAnnotations asAnnotations(Map<String, String> annotations) {
+        DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
+        annotations.entrySet().forEach(e -> {
+                if (e.getValue() != null) {
+                    builder.set(e.getKey(), e.getValue());
+                } else {
+                    builder.remove(e.getKey());
+                }
+            });
+        return builder.build();
+    }
+
+    // Utility class not intended for instantiation.
+    private GrpcDeviceUtils() {}
+}
