diff --git a/drivers/cisco/rest/src/main/java/org/onosproject/drivers/cisco/rest/DeviceDescriptionDiscoveryCisco9kImpl.java b/drivers/cisco/rest/src/main/java/org/onosproject/drivers/cisco/rest/DeviceDescriptionDiscoveryCisco9kImpl.java
new file mode 100644
index 0000000..03a118e
--- /dev/null
+++ b/drivers/cisco/rest/src/main/java/org/onosproject/drivers/cisco/rest/DeviceDescriptionDiscoveryCisco9kImpl.java
@@ -0,0 +1,263 @@
+/*
+ * Copyright 2016-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 org.onosproject.drivers.cisco.rest;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.JsonNodeType;
+import com.google.common.collect.Lists;
+import org.onlab.packet.ChassisId;
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DefaultDeviceDescription;
+import org.onosproject.net.device.DefaultPortDescription;
+import org.onosproject.net.device.DeviceDescription;
+import org.onosproject.net.device.DeviceDescriptionDiscovery;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.device.PortDescription;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.slf4j.Logger;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.StreamSupport;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Discovers the device, ports information from a Cisco Nexus 9K REST device.
+ */
+public class DeviceDescriptionDiscoveryCisco9kImpl extends AbstractHandlerBehaviour
+        implements DeviceDescriptionDiscovery {
+    private final Logger log = getLogger(getClass());
+
+    private static final String SHOW_INTERFACES_CMD = "show interface";
+    private static final String SHOW_VERSION_CMD = "show version";
+    private static final String SHOW_MODULE_CMD = "show module";
+
+    private static final String JSON_BODY = "body";
+    private static final String JSON_RESULT = "result";
+    private static final String JSON_INTERFACE = "interface";
+    private static final String JSON_ROW_INTERFACE = "ROW_interface";
+    private static final String JSON_ROW_MODULE = "ROW_modinfo";
+    private static final String JSON_ROW_MODULE_MAC = "ROW_modmacinfo";
+
+    private static final String MANUFACTURER = "manufacturer";
+    private static final String CHASSIS_ID = "chassis_id";
+    private static final String CISCO_SERIAL_BOARD = "proc_board_id";
+    private static final String KICKSTART_VER = "kickstart_ver_str";
+    private static final String INTERFACE_STATE = "state";
+    private static final String INTERFACE_ADMIN_STATE = "admin_state";
+    private static final String INTERFACE_ENABLED = "enabled";
+    private static final String INTERFACE_DISABLED = "disabled";
+    private static final String STATE_UP = "up";
+    private static final String MODULE_MODEL = "model";
+    private static final String MODULE_INTERFACE = "modinf";
+    private static final String MODULE_MAC = "modmac";
+    private static final String MODULE_SERIAL = "serialnum";
+
+    private static final String INTERFACE_ETHERNET = "Ethernet";
+    private static final String INTERFACE_PORTCHANNEL = "port-channel";
+    private static final String INTERFACE_BW = "eth_bw";
+    private static final String INTERFACE_MAC = "eth_bia_addr";
+    private static final String BREAKOUT = "breakout";
+    private static final String UNKNOWN = "unknown";
+
+    private static final String MODULE_ANNOTATION_FORMAT = "%s:%s:%s";
+    private static final String MODULE_BRACKET_FORMAT = "[%s]";
+
+    @Override
+    public DeviceDescription discoverDeviceDetails() {
+        DeviceId deviceId = handler().data().deviceId();
+
+        ArrayList<String> cmd = new ArrayList<>();
+        cmd.add(SHOW_VERSION_CMD);
+        cmd.add(SHOW_MODULE_CMD);
+
+        String response = NxApiRequest.postClis(handler(), cmd);
+
+        String mrf = UNKNOWN;
+        String hwVer = UNKNOWN;
+        String swVer = UNKNOWN;
+        String serialNum = UNKNOWN;
+        String module = UNKNOWN;
+
+        try {
+            ObjectMapper om = new ObjectMapper();
+            JsonNode json = om.readTree(response);
+
+            JsonNode body = json.at("/0/body");
+            if (!body.isMissingNode()) {
+                mrf = body.at("/" + MANUFACTURER).asText();
+                hwVer = body.at("/" + CHASSIS_ID).asText();
+                swVer = body.at("/" + KICKSTART_VER).asText();
+                serialNum = body.at("/" + CISCO_SERIAL_BOARD).asText();
+            }
+
+
+            JsonNode modInfo = json.at("/1/" + JSON_ROW_MODULE);
+            JsonNode modMacInfo = json.at("/1/" + JSON_ROW_MODULE_MAC);
+
+            if (!modInfo.isMissingNode()) {
+                List<String> modulesAnn = prepareModuleAnnotation(modInfo, modMacInfo);
+                module = String.format(MODULE_BRACKET_FORMAT, String.join(",", modulesAnn));
+            }
+        } catch (JsonParseException e) {
+            log.error("Failed to parse Json", e);
+        } catch (JsonMappingException e) {
+            log.error("Failed to map Json", e);
+        } catch (JsonProcessingException e) {
+            log.error("Failed to processing Json", e);
+        } catch (IOException e) {
+            log.error("Failed to retrieve Device Information", e);
+        }
+        DefaultAnnotations.Builder annotations = DefaultAnnotations.builder();
+
+        DeviceService deviceService = checkNotNull(handler().get(DeviceService.class));
+        Device device = deviceService.getDevice(deviceId);
+        if (device != null) {
+            annotations.putAll(device.annotations());
+        }
+
+        return new DefaultDeviceDescription(deviceId.uri(), Device.Type.SWITCH,
+                                            mrf, hwVer, swVer, serialNum,
+                                            new ChassisId(), annotations.build());
+    }
+
+    @Override
+    public List<PortDescription> discoverPortDetails() {
+        List<PortDescription> ports = Lists.newArrayList();
+
+        try {
+            String response;
+            try {
+                response = NxApiRequest.postCli(handler(), SHOW_INTERFACES_CMD);
+            } catch (NullPointerException e) {
+                log.error("Failed to perform {} command on the device {}",
+                          SHOW_INTERFACES_CMD, handler().data().deviceId());
+                return ports;
+            }
+
+            ObjectMapper om = new ObjectMapper();
+            JsonNode json = om.readTree(response);
+            JsonNode res = json.get(JSON_RESULT);
+            JsonNode interfaces = res.findValue(JSON_ROW_INTERFACE);
+            Iterator<JsonNode> iter = interfaces.elements();
+            Integer ifCount = 1;
+            while (iter.hasNext()) {
+                JsonNode ifs = iter.next();
+                String ifName = ifs.get(JSON_INTERFACE).asText();
+
+                if (isPortValid(ifName)) {
+                    Port.Type portType = Port.Type.VIRTUAL;
+                    long portSpeed = ifs.get(INTERFACE_BW).asLong() / 1000; //Mbps
+                    String portMac = ifs.get(INTERFACE_MAC).asText();
+                    MacAddress mac = MacAddress.valueOf(
+                            portMac.replace(".", "").replaceAll("(.{2})", "$1:").trim().substring(0, 17));
+                    boolean state = STATE_UP.equals(ifs.get(INTERFACE_STATE).asText());
+                    String adminState = STATE_UP.equals(ifs.get(INTERFACE_ADMIN_STATE).asText())
+                            ? INTERFACE_ENABLED : INTERFACE_DISABLED;
+
+                    DefaultAnnotations.Builder annotations = DefaultAnnotations.builder()
+                            .set(AnnotationKeys.PORT_NAME, ifName)
+                            .set(AnnotationKeys.PORT_MAC, mac.toString())
+                            .set(AnnotationKeys.ADMIN_STATE, adminState);
+
+                    if (isValidPhysicalPort(ifName)) {
+                        String interfaceNumber = ifName.replace(INTERFACE_ETHERNET, "");
+                        String[] interfaceLocation = interfaceNumber.split("/");
+                        portType = Port.Type.FIBER;
+
+                        if (interfaceLocation.length == 3) {
+                            String breakout = ifName.substring(0, ifName.lastIndexOf("/"));
+                            annotations.set(BREAKOUT, breakout);
+                        }
+                    }
+                    PortDescription desc = DefaultPortDescription.builder()
+                            .withPortNumber(PortNumber.portNumber(ifCount))
+                            .isEnabled(state)
+                            .type(portType).portSpeed(portSpeed).annotations(annotations.build())
+                            .build();
+                    ports.add(desc);
+                    ifCount++;
+                }
+            }
+        } catch (Exception e) {
+            log.error("Exception occurred because of ", e);
+        }
+
+        return ports;
+    }
+
+    private boolean isValidPhysicalPort(String portName) {
+        return portName.startsWith(INTERFACE_ETHERNET);
+    }
+
+    private boolean isValidVirtualPort(String portName) {
+        return portName.startsWith(INTERFACE_PORTCHANNEL);
+    }
+
+    private boolean isPortValid(String portName) {
+        return isValidPhysicalPort(portName) || isValidVirtualPort(portName);
+    }
+
+    private List<String> prepareModuleAnnotation(JsonNode modules, JsonNode macs) {
+        List<String> modulesInfo = new ArrayList<>();
+        if (modules.getNodeType() == JsonNodeType.ARRAY) {
+            modules.forEach(module -> modulesInfo.add(getModuleInfo(module, macs)));
+        } else if (modules.getNodeType() == JsonNodeType.OBJECT) {
+            modulesInfo.add(getModuleInfo(modules, macs));
+        }
+        return modulesInfo;
+    }
+
+    private String getModuleInfo(JsonNode module, JsonNode moduleMac) {
+        int moduleId = module.get(MODULE_INTERFACE).asInt();
+        String moduleModel = module.get(MODULE_MODEL).asText();
+        String moduleSerial = getModuleSerial(moduleId, moduleMac);
+        return String.format(MODULE_ANNOTATION_FORMAT, moduleId, moduleModel, moduleSerial);
+    }
+
+    private String getModuleSerial(int moduleId, JsonNode macs) {
+        if (macs.getNodeType() == JsonNodeType.ARRAY) {
+            Optional<JsonNode> serial = StreamSupport.stream(macs.spliterator(), false)
+                    .filter(mac -> mac.get(MODULE_MAC).asInt() == moduleId)
+                    .findAny();
+            if (serial.isPresent()) {
+                return serial.get().get(MODULE_SERIAL).asText();
+            }
+        } else if (macs.getNodeType() == JsonNodeType.OBJECT) {
+            if (macs.get(MODULE_MAC).asInt() == moduleId) {
+                return macs.get(MODULE_SERIAL).asText();
+            }
+        }
+        return UNKNOWN;
+    }
+
+}
