diff --git a/doc/source/command-objects/subnet.rst b/doc/source/command-objects/subnet.rst
new file mode 100644
index 0000000000..70a0eedfa1
--- /dev/null
+++ b/doc/source/command-objects/subnet.rst
@@ -0,0 +1,20 @@
+======
+subnet
+======
+
+Network v2
+
+subnet list
+-----------
+
+List subnets
+
+.. program:: subnet list
+.. code:: bash
+
+    os subnet list
+        [--long]
+
+.. option:: --long
+
+    List additional fields in output
diff --git a/doc/source/commands.rst b/doc/source/commands.rst
index f7e8b444d4..5c8ea1b2c8 100644
--- a/doc/source/commands.rst
+++ b/doc/source/commands.rst
@@ -116,6 +116,7 @@ referring to both Compute and Volume quotas.
 * ``service``: (**Identity**) a cloud service
 * ``service provider``: (**Identity**) a resource that consumes assertions from an ``identity provider``
 * ``snapshot``: (**Volume**) a point-in-time copy of a volume
+* ``subnet``: (**Network**) - a pool of private IP addresses that can be assigned to instances or other resources
 * ``token``: (**Identity**) a bearer token managed by Identity service
 * ``usage``: (**Compute**) display host resources being consumed
 * ``user``: (**Identity**) individual cloud resources users
diff --git a/openstackclient/network/v2/subnet.py b/openstackclient/network/v2/subnet.py
new file mode 100644
index 0000000000..cd0e52ffcb
--- /dev/null
+++ b/openstackclient/network/v2/subnet.py
@@ -0,0 +1,70 @@
+#   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.
+#
+
+"""Subnet action implementations"""
+
+import logging
+
+from cliff import lister
+
+from openstackclient.common import utils
+
+
+def _format_allocation_pools(data):
+    pool_formatted = ['%s-%s' % (pool.get('start', ''), pool.get('end', ''))
+                      for pool in data]
+    return ','.join(pool_formatted)
+
+
+_formatters = {
+    'allocation_pools': _format_allocation_pools,
+    'dns_nameservers': utils.format_list,
+    'host_routes': utils.format_list,
+}
+
+
+class ListSubnet(lister.Lister):
+    """List subnets"""
+
+    log = logging.getLogger(__name__ + '.ListSubnet')
+
+    def get_parser(self, prog_name):
+        parser = super(ListSubnet, self).get_parser(prog_name)
+        parser.add_argument(
+            '--long',
+            action='store_true',
+            default=False,
+            help='List additional fields in output',
+        )
+        return parser
+
+    def take_action(self, parsed_args):
+        self.log.debug('take_action(%s)' % parsed_args)
+
+        data = self.app.client_manager.network.subnets()
+
+        headers = ('ID', 'Name', 'Network', 'CIDR')
+        columns = ('id', 'name', 'network_id', 'cidr')
+        if parsed_args.long:
+            headers += ('Project', 'DHCP', 'DNS Nameservers',
+                        'Allocation Pools', 'Host Routes', 'IP Version',
+                        'Gateway')
+            columns += ('tenant_id', 'enable_dhcp', 'dns_nameservers',
+                        'allocation_pools', 'host_routes', 'ip_version',
+                        'gateway_ip')
+
+        return (headers,
+                (utils.get_item_properties(
+                    s, columns,
+                    formatters=_formatters,
+                ) for s in data))
diff --git a/openstackclient/tests/network/v2/fakes.py b/openstackclient/tests/network/v2/fakes.py
index de885c62ab..6085bfbd50 100644
--- a/openstackclient/tests/network/v2/fakes.py
+++ b/openstackclient/tests/network/v2/fakes.py
@@ -304,3 +304,71 @@ class FakeRouter(object):
         if routers is None:
             routers = FakeRouter.create_routers(count)
         return mock.MagicMock(side_effect=routers)
+
+
+class FakeSubnet(object):
+    """Fake one or more subnets."""
+
+    @staticmethod
+    def create_one_subnet(attrs={}, methods={}):
+        """Create a fake subnet.
+
+        :param Dictionary attrs:
+            A dictionary with all attributes
+        :param Dictionary methods:
+            A dictionary with all methods
+        :return:
+            A FakeResource object faking the subnet
+        """
+        # Set default attributes.
+        subnet_attrs = {
+            'id': 'subnet-id-' + uuid.uuid4().hex,
+            'name': 'subnet-name-' + uuid.uuid4().hex,
+            'network_id': 'network-id-' + uuid.uuid4().hex,
+            'cidr': '10.10.10.0/24',
+            'tenant_id': 'project-id-' + uuid.uuid4().hex,
+            'enable_dhcp': True,
+            'dns_nameservers': [],
+            'allocation_pools': [],
+            'host_routes': [],
+            'ip_version': '4',
+            'gateway_ip': '10.10.10.1',
+        }
+
+        # Overwrite default attributes.
+        subnet_attrs.update(attrs)
+
+        # Set default methods.
+        subnet_methods = {
+            'keys': ['id', 'name', 'network_id', 'cidr', 'enable_dhcp',
+                     'allocation_pools', 'dns_nameservers', 'gateway_ip',
+                     'host_routes', 'ip_version', 'tenant_id']
+        }
+
+        # Overwrite default methods.
+        subnet_methods.update(methods)
+
+        subnet = fakes.FakeResource(info=copy.deepcopy(subnet_attrs),
+                                    methods=copy.deepcopy(subnet_methods),
+                                    loaded=True)
+
+        return subnet
+
+    @staticmethod
+    def create_subnets(attrs={}, methods={}, count=2):
+        """Create multiple fake subnets.
+
+        :param Dictionary attrs:
+            A dictionary with all attributes
+        :param Dictionary methods:
+            A dictionary with all methods
+        :param int count:
+            The number of subnets to fake
+        :return:
+            A list of FakeResource objects faking the subnets
+        """
+        subnets = []
+        for i in range(0, count):
+            subnets.append(FakeSubnet.create_one_subnet(attrs, methods))
+
+        return subnets
diff --git a/openstackclient/tests/network/v2/test_subnet.py b/openstackclient/tests/network/v2/test_subnet.py
new file mode 100644
index 0000000000..74b4d33283
--- /dev/null
+++ b/openstackclient/tests/network/v2/test_subnet.py
@@ -0,0 +1,108 @@
+#   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.
+#
+
+import mock
+
+from openstackclient.common import utils
+from openstackclient.network.v2 import subnet as subnet_v2
+from openstackclient.tests.network.v2 import fakes as network_fakes
+
+
+class TestSubnet(network_fakes.TestNetworkV2):
+    def setUp(self):
+        super(TestSubnet, self).setUp()
+
+        # Get a shortcut to the network client
+        self.network = self.app.client_manager.network
+
+
+class TestListSubnet(TestSubnet):
+    # The subnets going to be listed up.
+    _subnet = network_fakes.FakeSubnet.create_subnets(count=3)
+
+    columns = (
+        'ID',
+        'Name',
+        'Network',
+        'CIDR'
+    )
+    columns_long = columns + (
+        'Project',
+        'DHCP',
+        'DNS Nameservers',
+        'Allocation Pools',
+        'Host Routes',
+        'IP Version',
+        'Gateway'
+    )
+
+    data = []
+    for subnet in _subnet:
+        data.append((
+            subnet.id,
+            subnet.name,
+            subnet.network_id,
+            subnet.cidr,
+        ))
+
+    data_long = []
+    for subnet in _subnet:
+        data_long.append((
+            subnet.id,
+            subnet.name,
+            subnet.network_id,
+            subnet.cidr,
+            subnet.tenant_id,
+            subnet.enable_dhcp,
+            utils.format_list(subnet.dns_nameservers),
+            subnet_v2._format_allocation_pools(subnet.allocation_pools),
+            utils.format_list(subnet.host_routes),
+            subnet.ip_version,
+            subnet.gateway_ip
+        ))
+
+    def setUp(self):
+        super(TestListSubnet, self).setUp()
+
+        # Get the command object to test
+        self.cmd = subnet_v2.ListSubnet(self.app, self.namespace)
+
+        self.network.subnets = mock.Mock(return_value=self._subnet)
+
+    def test_subnet_list_no_options(self):
+        arglist = []
+        verifylist = [
+            ('long', False),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = self.cmd.take_action(parsed_args)
+
+        self.network.subnets.assert_called_with()
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.data, list(data))
+
+    def test_subnet_list_long(self):
+        arglist = [
+            '--long',
+        ]
+        verifylist = [
+            ('long', True),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = self.cmd.take_action(parsed_args)
+
+        self.network.subnets.assert_called_with()
+        self.assertEqual(self.columns_long, columns)
+        self.assertEqual(self.data_long, list(data))
diff --git a/setup.cfg b/setup.cfg
index 7e0f0b4c8e..98baeee4d1 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -339,6 +339,7 @@ openstack.network.v2 =
     router_list = openstackclient.network.v2.router:ListRouter
     router_set = openstackclient.network.v2.router:SetRouter
     router_show = openstackclient.network.v2.router:ShowRouter
+    subnet_list = openstackclient.network.v2.subnet:ListSubnet
 
 openstack.object_store.v1 =
     object_store_account_set = openstackclient.object.v1.account:SetAccount