diff --git a/cli/src/main/java/org/onosproject/cli/net/GetFlowStatisticsCommand.java b/cli/src/main/java/org/onosproject/cli/net/GetFlowStatisticsCommand.java
new file mode 100644
index 0000000..1cc6019
--- /dev/null
+++ b/cli/src/main/java/org/onosproject/cli/net/GetFlowStatisticsCommand.java
@@ -0,0 +1,321 @@
+/*
+ * Copyright 2015-present 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.cli.net;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.ConnectPoint;
+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.DeviceService;
+import org.onosproject.net.flow.TypedStoredFlowEntry;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.statistic.FlowStatisticService;
+import org.onosproject.net.statistic.SummaryFlowEntryWithLoad;
+import org.onosproject.net.statistic.TypedFlowEntryWithLoad;
+
+import java.util.List;
+import java.util.Map;
+
+import static org.onosproject.net.DeviceId.deviceId;
+import static org.onosproject.net.PortNumber.portNumber;
+
+/**
+ * Fetches flow statistics with a flow type and instruction type.
+ */
+@Command(scope = "onos", name = "get-flow-stats",
+        description = "Fetches flow stats for a connection point with given flow type and instruction type")
+public class GetFlowStatisticsCommand extends AbstractShellCommand {
+    @Argument(index = 0, name = "devicePort",
+            description = "Device[/Port] connectPoint Description",
+            required = true, multiValued = false)
+    String devicePort = null;
+
+    @Option(name = "-s", aliases = "--summary",
+            description = "Show flow stats summary",
+            required = false, multiValued = false)
+    boolean showSummary = true; // default summary
+
+    @Option(name = "-a", aliases = "--all",
+            description = "Show flow stats all",
+            required = false, multiValued = false)
+    boolean showAll = false;
+
+    @Option(name = "-t", aliases = "--topn",
+            description = "Show flow stats topn",
+            required = false, multiValued = false)
+    String showTopn = null;
+
+    @Option(name = "-f", aliases = "--flowType",
+            description = "Flow live type, It includes IMMEDIATE, SHORT, MID, LONG, UNKNOWN"
+                          + ", and is valid with -a or -t option only",
+            required = false, multiValued = false)
+    String flowLiveType = null;
+
+    @Option(name = "-i", aliases = "--instructionType",
+            description = "Flow instruction type, It includes DROP, OUTPUT, GROUP, L0MODIFICATION, L2MODIFICATION,"
+                    + " TABLE, L3MODIFICATION, METADATA"
+                    + ", and is valid with -a or -t option only",
+            required = false, multiValued = false)
+    String instructionType = null;
+
+    @Override
+    protected void execute() {
+        DeviceService deviceService = get(DeviceService.class);
+        FlowStatisticService flowStatsService = get(FlowStatisticService.class);
+
+        String deviceUri = getDeviceId(devicePort);
+        String portUri = getPortNumber(devicePort);
+
+        DeviceId ingressDeviceId = deviceId(deviceUri);
+        PortNumber ingressPortNumber;
+        if (portUri.length() == 0) {
+            ingressPortNumber = null;
+        } else {
+            ingressPortNumber = portNumber(portUri);
+        }
+
+        Device device = deviceService.getDevice(ingressDeviceId);
+        if (device == null) {
+            error("No such device %s", ingressDeviceId.uri());
+            return;
+        }
+
+        if (ingressPortNumber != null) {
+            Port port = deviceService.getPort(ingressDeviceId, ingressPortNumber);
+            if (port == null) {
+                error("No such port %s on device %s", portUri, ingressDeviceId.uri());
+                return;
+            }
+        }
+
+        if (flowLiveType != null) {
+            flowLiveType = flowLiveType.toUpperCase();
+        }
+        if (instructionType != null) {
+            instructionType = instructionType.toUpperCase();
+        }
+
+        // convert String to FlowLiveType and check validity
+        TypedStoredFlowEntry.FlowLiveType inLiveType;
+        if (flowLiveType == null) {
+            inLiveType = null;
+        } else {
+            inLiveType = getFlowLiveType(flowLiveType);
+            if (inLiveType == null) {
+                error("Invalid flow live type [%s] error", flowLiveType);
+                return;
+            }
+        }
+        // convert String to InstructionType and check validity
+        Instruction.Type inInstructionType;
+        if (instructionType == null) {
+            inInstructionType = null;
+        } else {
+            inInstructionType = getInstructionType(instructionType);
+            if (inInstructionType == null) {
+                error("Invalid instruction type [%s] error", instructionType);
+                return;
+            }
+        }
+
+        if (showTopn != null) {
+            int topn = Integer.parseInt(showTopn);
+
+            if (topn <= 0) {
+                topn = 100; //default value
+            } else if (topn > 1000) {
+                topn = 1000; //max value
+            }
+
+            // print show topn head line with type
+            print("deviceId=%s, show TOPN=%s flows, live type=%s, instruction type=%s",
+                    deviceUri,
+                    Integer.toString(topn),
+                    flowLiveType == null ? "ALL" : flowLiveType,
+                    instructionType == null ? "ALL" : instructionType);
+            if (ingressPortNumber == null) {
+                Map<ConnectPoint, List<TypedFlowEntryWithLoad>> typedFlowLoadMap =
+                          flowStatsService.loadTopnByType(device, inLiveType, inInstructionType, topn);
+                // print all ports topn flows load for a given device
+                for (ConnectPoint cp : typedFlowLoadMap.keySet()) {
+                    printPortFlowsLoad(cp, typedFlowLoadMap.get(cp));
+                }
+            } else {
+                List<TypedFlowEntryWithLoad> typedFlowLoad =
+                        flowStatsService.loadTopnByType(device, ingressPortNumber, inLiveType, inInstructionType, topn);
+                // print device/port topn flows load
+                ConnectPoint cp = new ConnectPoint(ingressDeviceId, ingressPortNumber);
+                printPortFlowsLoad(cp, typedFlowLoad);
+            }
+        } else if (showAll) { // is true?
+            // print show all head line with type
+            print("deviceId=%s, show ALL flows, live type=%s, instruction type=%s",
+                    deviceUri,
+                    flowLiveType == null ? "ALL" : flowLiveType,
+                    instructionType == null ? "ALL" : instructionType);
+            if (ingressPortNumber == null) {
+                Map<ConnectPoint, List<TypedFlowEntryWithLoad>> typedFlowLoadMap =
+                        flowStatsService.loadAllByType(device, inLiveType, inInstructionType);
+                // print all ports all flows load for a given device
+                for (ConnectPoint cp : typedFlowLoadMap.keySet()) {
+                    printPortFlowsLoad(cp, typedFlowLoadMap.get(cp));
+                }
+            } else {
+                List<TypedFlowEntryWithLoad> typedFlowLoad =
+                        flowStatsService.loadAllByType(device, ingressPortNumber, inLiveType, inInstructionType);
+                // print device/port all flows load
+                ConnectPoint cp = new ConnectPoint(ingressDeviceId, ingressPortNumber);
+                printPortFlowsLoad(cp, typedFlowLoad);
+            }
+        } else { // if (showSummary == true) //always is true
+            // print show summary head line
+            print("deviceId=%s, show SUMMARY flows", deviceUri);
+            if (ingressPortNumber == null) {
+                Map<ConnectPoint, SummaryFlowEntryWithLoad> summaryFlowLoadMap =
+                        flowStatsService.loadSummary(device);
+                // print all ports flow load summary for a given device
+                for (ConnectPoint cp : summaryFlowLoadMap.keySet()) {
+                    printPortSummaryLoad(cp, summaryFlowLoadMap.get(cp));
+                }
+            } else {
+                SummaryFlowEntryWithLoad summaryFlowLoad =
+                        flowStatsService.loadSummary(device, ingressPortNumber);
+                // print device/port flow load summary
+                ConnectPoint cp = new ConnectPoint(ingressDeviceId, ingressPortNumber);
+                printPortSummaryLoad(cp, summaryFlowLoad);
+            }
+        }
+    }
+
+    /**
+     * Extracts the port number portion of the ConnectPoint.
+     *
+     * @param deviceString string representing the device/port
+     * @return port number as a string, empty string if the port is not found
+     */
+    private String getPortNumber(String deviceString) {
+        if (deviceString == null) {
+            return "";
+        }
+
+        int slash = deviceString.indexOf('/');
+        if (slash <= 0) {
+            return ""; // return when no port number
+        }
+        return deviceString.substring(slash + 1, deviceString.length());
+    }
+
+    /**
+     * Extracts the device ID portion of the ConnectPoint.
+     *
+     * @param deviceString string representing the device/port
+     * @return device ID string
+     */
+    private String getDeviceId(String deviceString) {
+        if (deviceString == null) {
+            return "";
+        }
+
+        int slash = deviceString.indexOf('/');
+        if (slash <= 0) {
+            return deviceString; // return only included device ID
+        }
+        return deviceString.substring(0, slash);
+    }
+
+    /**
+     * converts string of flow live type to FloeLiveType enum.
+     *
+     * @param liveType string representing the flow live type
+     * @return TypedStoredFlowEntry.FlowLiveType
+     */
+    private TypedStoredFlowEntry.FlowLiveType getFlowLiveType(String liveType) {
+        String liveTypeUC = liveType.toUpperCase();
+
+        if (liveTypeUC.equals("IMMEDIATE")) {
+            return TypedStoredFlowEntry.FlowLiveType.IMMEDIATE_FLOW;
+        } else if (liveTypeUC.equals("SHORT")) {
+            return TypedStoredFlowEntry.FlowLiveType.SHORT_FLOW;
+        } else if (liveTypeUC.equals("MID")) {
+            return TypedStoredFlowEntry.FlowLiveType.MID_FLOW;
+        } else if (liveTypeUC.equals("LONG")) {
+            return TypedStoredFlowEntry.FlowLiveType.LONG_FLOW;
+        } else if (liveTypeUC.equals("UNKNOWN")) {
+            return TypedStoredFlowEntry.FlowLiveType.UNKNOWN_FLOW;
+        } else {
+            return null; // flow live type error
+        }
+    }
+
+    /**
+     * converts string of instruction type to Instruction type enum.
+     *
+     * @param instType string representing the instruction type
+     * @return Instruction.Type
+     */
+    private Instruction.Type getInstructionType(String instType) {
+        String instTypeUC = instType.toUpperCase();
+
+        if (instTypeUC.equals("OUTPUT")) {
+            return Instruction.Type.OUTPUT;
+        } else if (instTypeUC.equals("GROUP")) {
+            return Instruction.Type.GROUP;
+        } else if (instTypeUC.equals("L0MODIFICATION")) {
+            return Instruction.Type.L0MODIFICATION;
+        } else if (instTypeUC.equals("L2MODIFICATION")) {
+            return Instruction.Type.L2MODIFICATION;
+        } else if (instTypeUC.equals("TABLE")) {
+            return Instruction.Type.TABLE;
+        } else if (instTypeUC.equals("L3MODIFICATION")) {
+            return Instruction.Type.L3MODIFICATION;
+        } else if (instTypeUC.equals("METADATA")) {
+            return Instruction.Type.METADATA;
+        } else {
+             return null; // instruction type error
+        }
+    }
+
+    private void printPortFlowsLoad(ConnectPoint cp, List<TypedFlowEntryWithLoad> typedFlowLoad) {
+       print("  deviceId/Port=%s/%s, %s flows", cp.elementId(), cp.port(), typedFlowLoad.size());
+        for (TypedFlowEntryWithLoad tfel: typedFlowLoad) {
+            TypedStoredFlowEntry tfe =  tfel.typedStoredFlowEntry();
+            print("    flowId=%s, state=%s, liveType=%s, life=%s -> %s",
+                    Long.toHexString(tfe.id().value()),
+                    tfe.state(),
+                    tfe.flowLiveType(),
+                    tfe.life(),
+                    tfel.load().isValid() ? tfel.load() : "Load{rate=0, NOT VALID}");
+        }
+    }
+
+    private void printPortSummaryLoad(ConnectPoint cp, SummaryFlowEntryWithLoad summaryFlowLoad) {
+        print("  deviceId/Port=%s/%s, Total=%s, Immediate=%s, Short=%s, Mid=%s, Long=%s, Unknown=%s",
+                cp.elementId(),
+                cp.port(),
+                summaryFlowLoad.totalLoad().isValid() ? summaryFlowLoad.totalLoad() : "Load{rate=0, NOT VALID}",
+                summaryFlowLoad.immediateLoad().isValid() ? summaryFlowLoad.immediateLoad() : "Load{rate=0, NOT VALID}",
+                summaryFlowLoad.shortLoad().isValid() ? summaryFlowLoad.shortLoad() : "Load{rate=0, NOT VALID}",
+                summaryFlowLoad.midLoad().isValid() ? summaryFlowLoad.midLoad() : "Load{rate=0, NOT VALID}",
+                summaryFlowLoad.longLoad().isValid() ? summaryFlowLoad.longLoad() : "Load{rate=0, NOT VALID}",
+                summaryFlowLoad.unknownLoad().isValid() ? summaryFlowLoad.unknownLoad() : "Load{rate=0, NOT VALID}");
+    }
+}
