diff --git a/apps/routing/src/main/java/org/onosproject/routing/cli/BgpRoutesListCommand.java b/apps/routing/src/main/java/org/onosproject/routing/cli/BgpRoutesListCommand.java
new file mode 100644
index 0000000..3b032c0
--- /dev/null
+++ b/apps/routing/src/main/java/org/onosproject/routing/cli/BgpRoutesListCommand.java
@@ -0,0 +1,283 @@
+/*
+ * Copyright 2014 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.routing.cli;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.routing.bgp.BgpConstants.Update;
+import org.onosproject.routing.bgp.BgpInfoService;
+import org.onosproject.routing.bgp.BgpRouteEntry;
+import org.onosproject.routing.bgp.BgpSession;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * Command to show the routes learned through BGP.
+ */
+@Command(scope = "onos", name = "bgp-routes",
+         description = "Lists all BGP best routes")
+public class BgpRoutesListCommand extends AbstractShellCommand {
+    @Option(name = "-s", aliases = "--summary",
+            description = "BGP routes summary",
+            required = false, multiValued = false)
+    private boolean routesSummary = false;
+
+    @Option(name = "-n", aliases = "--neighbor",
+            description = "Routes from a BGP neighbor",
+            required = false, multiValued = false)
+    private String bgpNeighbor;
+
+    private static final String FORMAT_SUMMARY_V4 =
+        "Total BGP IPv4 routes = %d";
+    private static final String FORMAT_SUMMARY_V6 =
+        "Total BGP IPv6 routes = %d";
+    private static final String FORMAT_HEADER =
+        "   Network            Next Hop        Origin LocalPref       MED BGP-ID";
+    private static final String FORMAT_ROUTE_LINE1 =
+        "   %-18s %-15s %6s %9s %9s %-15s";
+    private static final String FORMAT_ROUTE_LINE2 =
+        "                      AsPath %s";
+
+    @Override
+    protected void execute() {
+        BgpInfoService service = AbstractShellCommand.get(BgpInfoService.class);
+
+        // Print summary of the routes
+        if (routesSummary) {
+            printSummary(service.getBgpRoutes4(), service.getBgpRoutes6());
+            return;
+        }
+
+        BgpSession foundBgpSession = null;
+        if (bgpNeighbor != null) {
+            // Print the routes from a single neighbor (if found)
+            for (BgpSession bgpSession : service.getBgpSessions()) {
+                if (bgpSession.remoteInfo().bgpId().toString().equals(bgpNeighbor)) {
+                    foundBgpSession = bgpSession;
+                    break;
+                }
+            }
+            if (foundBgpSession == null) {
+                print("BGP neighbor %s not found", bgpNeighbor);
+                return;
+            }
+        }
+
+        // Print the routes
+        if (foundBgpSession != null) {
+            printRoutes(foundBgpSession.getBgpRibIn4(),
+                        foundBgpSession.getBgpRibIn6());
+        } else {
+            printRoutes(service.getBgpRoutes4(), service.getBgpRoutes6());
+        }
+    }
+
+    /**
+     * Prints summary of the routes.
+     *
+     * @param routes4 the IPv4 routes
+     * @param routes6 the IPv6 routes
+     */
+    private void printSummary(Collection<BgpRouteEntry> routes4,
+                              Collection<BgpRouteEntry> routes6) {
+        if (outputJson()) {
+            ObjectMapper mapper = new ObjectMapper();
+            ObjectNode result = mapper.createObjectNode();
+            result.put("totalRoutes4", routes4.size());
+            result.put("totalRoutes6", routes6.size());
+            print("%s", result);
+        } else {
+            print(FORMAT_SUMMARY_V4, routes4.size());
+            print(FORMAT_SUMMARY_V6, routes6.size());
+        }
+    }
+
+    /**
+     * Prints all routes.
+     *
+     * @param routes4 the IPv4 routes to print
+     * @param routes6 the IPv6 routes to print
+     */
+    private void printRoutes(Collection<BgpRouteEntry> routes4,
+                             Collection<BgpRouteEntry> routes6) {
+        if (outputJson()) {
+            ObjectMapper mapper = new ObjectMapper();
+            ObjectNode result = mapper.createObjectNode();
+            result.put("routes4", json(routes4));
+            result.put("routes6", json(routes6));
+            print("%s", result);
+        } else {
+            // The IPv4 routes
+            print(FORMAT_HEADER);
+            for (BgpRouteEntry route : routes4) {
+                printRoute(route);
+            }
+            print(FORMAT_SUMMARY_V4, routes4.size());
+            print("");                  // Empty separator line
+            // The IPv6 routes
+            print(FORMAT_HEADER);
+            for (BgpRouteEntry route : routes6) {
+                printRoute(route);
+            }
+            print(FORMAT_SUMMARY_V6, routes6.size());
+        }
+    }
+
+    /**
+     * Prints a BGP route.
+     *
+     * @param route the route to print
+     */
+    private void printRoute(BgpRouteEntry route) {
+        if (route != null) {
+            print(FORMAT_ROUTE_LINE1, route.prefix(), route.nextHop(),
+                  Update.Origin.typeToString(route.getOrigin()),
+                  route.getLocalPref(), route.getMultiExitDisc(),
+                  route.getBgpSession().remoteInfo().bgpId());
+            print(FORMAT_ROUTE_LINE2, asPath4Cli(route.getAsPath()));
+        }
+    }
+
+    /**
+     * Formats the AS Path as a string that can be shown on the CLI.
+     *
+     * @param asPath the AS Path to format
+     * @return the AS Path as a string
+     */
+    private String asPath4Cli(BgpRouteEntry.AsPath asPath) {
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments =
+            asPath.getPathSegments();
+
+        if (pathSegments.isEmpty()) {
+            return "[none]";
+        }
+
+        final StringBuilder builder = new StringBuilder();
+        for (BgpRouteEntry.PathSegment pathSegment : pathSegments) {
+            String prefix = null;
+            String suffix = null;
+            switch (pathSegment.getType()) {
+            case Update.AsPath.AS_SET:
+                prefix = "[AS-Set";
+                suffix = "]";
+                break;
+            case Update.AsPath.AS_SEQUENCE:
+                break;
+            case Update.AsPath.AS_CONFED_SEQUENCE:
+                prefix = "[AS-Confed-Seq";
+                suffix = "]";
+                break;
+            case Update.AsPath.AS_CONFED_SET:
+                prefix = "[AS-Confed-Set";
+                suffix = "]";
+                break;
+            default:
+                builder.append(String.format("(type = %s)",
+                        Update.AsPath.typeToString(pathSegment.getType())));
+                break;
+            }
+
+            if (prefix != null) {
+                if (builder.length() > 0) {
+                    builder.append(" ");        // Separator
+                }
+                builder.append(prefix);
+            }
+            // Print the AS numbers
+            for (Long asn : pathSegment.getSegmentAsNumbers()) {
+                if (builder.length() > 0) {
+                    builder.append(" ");        // Separator
+                }
+                builder.append(String.format("%d", asn));
+            }
+            if (suffix != null) {
+                // No need for separator
+                builder.append(prefix);
+            }
+        }
+        return builder.toString();
+    }
+
+    /**
+     * Produces a JSON array of routes.
+     *
+     * @param routes the routes with the data
+     * @return JSON array with the routes
+     */
+    private JsonNode json(Collection<BgpRouteEntry> routes) {
+        ObjectMapper mapper = new ObjectMapper();
+        ArrayNode result = mapper.createArrayNode();
+
+        for (BgpRouteEntry route : routes) {
+            result.add(json(mapper, route));
+        }
+        return result;
+    }
+
+    /**
+     * Produces JSON object for a route.
+     *
+     * @param mapper the JSON object mapper to use
+     * @param route the route with the data
+     * @return JSON object for the route
+     */
+    private ObjectNode json(ObjectMapper mapper, BgpRouteEntry route) {
+        ObjectNode result = mapper.createObjectNode();
+
+        result.put("prefix", route.prefix().toString());
+        result.put("nextHop", route.nextHop().toString());
+        result.put("bgpId",
+                   route.getBgpSession().remoteInfo().bgpId().toString());
+        result.put("origin", Update.Origin.typeToString(route.getOrigin()));
+        result.put("asPath", json(mapper, route.getAsPath()));
+        result.put("localPref", route.getLocalPref());
+        result.put("multiExitDisc", route.getMultiExitDisc());
+
+        return result;
+    }
+
+    /**
+     * Produces JSON object for an AS path.
+     *
+     * @param mapper the JSON object mapper to use
+     * @param asPath the AS path with the data
+     * @return JSON object for the AS path
+     */
+    private ObjectNode json(ObjectMapper mapper, BgpRouteEntry.AsPath asPath) {
+        ObjectNode result = mapper.createObjectNode();
+        ArrayNode pathSegmentsJson = mapper.createArrayNode();
+        for (BgpRouteEntry.PathSegment pathSegment : asPath.getPathSegments()) {
+            ObjectNode pathSegmentJson = mapper.createObjectNode();
+            pathSegmentJson.put("type",
+                                Update.AsPath.typeToString(pathSegment.getType()));
+            ArrayNode segmentAsNumbersJson = mapper.createArrayNode();
+            for (Long asNumber : pathSegment.getSegmentAsNumbers()) {
+                segmentAsNumbersJson.add(asNumber);
+            }
+            pathSegmentJson.put("segmentAsNumbers", segmentAsNumbersJson);
+            pathSegmentsJson.add(pathSegmentJson);
+        }
+        result.put("pathSegments", pathSegmentsJson);
+
+        return result;
+    }
+}
