diff --git a/doc/source/command-objects/subnet.rst b/doc/source/command-objects/subnet.rst
index 56a28d737d..eb64c9e732 100644
--- a/doc/source/command-objects/subnet.rst
+++ b/doc/source/command-objects/subnet.rst
@@ -21,7 +21,7 @@ Delete a subnet
     Subnet to delete (name or ID)
 
 subnet create
---------------
+-------------
 
 Create new subnet
 
@@ -143,6 +143,65 @@ List subnets
 
     List additional fields in output
 
+subnet set
+----------
+
+Set subnet properties
+
+.. program:: subnet set
+.. code:: bash
+
+    os subnet set
+        [--allocation-pool start=<ip-address>,end=<ip-address>]
+        [--dhcp | --no-dhcp]
+        [--dns-nameserver <dns-nameserver>]
+        [--gateway <gateway-ip>]
+        [--host-route destination=<subnet>,gateway=<ip-address>]
+        [--name <new-name>]
+        <subnet>
+
+.. option:: --allocation-pool start=<ip-address>,end=<ip-address>
+
+    Allocation pool IP addresses for this subnet e.g.:
+        start=192.168.199.2,end=192.168.199.254 (This option can be repeated)
+
+.. option:: --dhcp
+
+     Enable DHCP
+
+.. option:: --no-dhcp
+
+     Disable DHCP
+
+.. option:: --dns-nameserver <dns-nameserver>
+
+     DNS name server for this subnet (This option can be repeated)
+
+.. option:: --gateway <gateway>
+
+     Specify a gateway for the subnet. The options are:
+         <ip-address>: Specific IP address to use as the gateway
+         'none':       This subnet will not use a gateway
+         e.g.: --gateway 192.168.9.1, --gateway none
+
+.. option:: --host-route destination=<subnet>,gateway=<ip-address>
+
+     Additional route for this subnet e.g.:
+         destination=10.10.0.0/16,gateway=192.168.71.254
+         destination: destination subnet (in CIDR notation)
+         gateway: nexthop IP address
+         (This option can be repeated)
+
+.. option:: --name
+
+     Updated name of the subnet
+
+.. _subnet_set-subnet:
+.. describe:: <subnet>
+
+    Subnet to modify (name or ID)
+
+
 subnet show
 -----------
 
diff --git a/functional/tests/network/v2/test_subnet.py b/functional/tests/network/v2/test_subnet.py
index afecfab07b..7697e0f4e6 100644
--- a/functional/tests/network/v2/test_subnet.py
+++ b/functional/tests/network/v2/test_subnet.py
@@ -12,8 +12,6 @@
 
 import uuid
 
-import testtools
-
 from functional.common import test
 
 
@@ -49,7 +47,6 @@ class SubnetTests(test.TestCase):
         raw_output = self.openstack('subnet list' + opts)
         self.assertIn(self.NAME, raw_output)
 
-    @testtools.skip('bug/1542363')
     def test_subnet_set(self):
         self.openstack('subnet set --no-dhcp ' + self.NAME)
         opts = self.get_show_opts(['name', 'enable_dhcp'])
diff --git a/openstackclient/network/v2/subnet.py b/openstackclient/network/v2/subnet.py
index 794c787f07..da4f6536ec 100644
--- a/openstackclient/network/v2/subnet.py
+++ b/openstackclient/network/v2/subnet.py
@@ -17,6 +17,7 @@ import copy
 from json.encoder import JSONEncoder
 
 from openstackclient.common import command
+from openstackclient.common import exceptions
 from openstackclient.common import parseractions
 from openstackclient.common import utils
 from openstackclient.identity import common as identity_common
@@ -42,6 +43,39 @@ _formatters = {
 }
 
 
+def _get_common_parse_arguments(parser):
+    parser.add_argument(
+        '--allocation-pool',
+        metavar='start=<ip-address>,end=<ip-address>',
+        dest='allocation_pools',
+        action=parseractions.MultiKeyValueAction,
+        required_keys=['start', 'end'],
+        help='Allocation pool IP addresses for this subnet '
+             'e.g.: start=192.168.199.2,end=192.168.199.254 '
+             '(This option can be repeated)',
+    )
+    parser.add_argument(
+        '--dns-nameserver',
+        metavar='<dns-nameserver>',
+        action='append',
+        dest='dns_nameservers',
+        help='DNS name server for this subnet '
+             '(This option can be repeated)',
+    )
+    parser.add_argument(
+        '--host-route',
+        metavar='destination=<subnet>,gateway=<ip-address>',
+        dest='host_routes',
+        action=parseractions.MultiKeyValueAction,
+        required_keys=['destination', 'gateway'],
+        help='Additional route for this subnet '
+             'e.g.: destination=10.10.0.0/16,gateway=192.168.71.254 '
+             'destination: destination subnet (in CIDR notation) '
+             'gateway: nexthop IP address '
+             '(This option can be repeated)',
+    )
+
+
 def _get_columns(item):
     columns = list(item.keys())
     if 'tenant_id' in columns:
@@ -70,57 +104,66 @@ def convert_entries_to_gateway(entries):
     return changed_entries
 
 
-def _get_attrs(client_manager, parsed_args):
+def _get_attrs(client_manager, parsed_args, is_create=True):
     attrs = {}
-    if parsed_args.name is not None:
+    if 'name' in parsed_args and parsed_args.name is not None:
         attrs['name'] = str(parsed_args.name)
 
-    if 'project' in parsed_args and parsed_args.project is not None:
-        identity_client = client_manager.identity
-        project_id = identity_common.find_project(
-            identity_client,
-            parsed_args.project,
-            parsed_args.project_domain,
-        ).id
-        attrs['tenant_id'] = project_id
+    if is_create:
+        if 'project' in parsed_args and parsed_args.project is not None:
+            identity_client = client_manager.identity
+            project_id = identity_common.find_project(
+                identity_client,
+                parsed_args.project,
+                parsed_args.project_domain,
+            ).id
+            attrs['tenant_id'] = project_id
+        client = client_manager.network
+        attrs['network_id'] = client.find_network(parsed_args.network,
+                                                  ignore_missing=False).id
+        if parsed_args.subnet_pool is not None:
+            subnet_pool = client.find_subnet_pool(parsed_args.subnet_pool,
+                                                  ignore_missing=False)
+            attrs['subnetpool_id'] = subnet_pool.id
+        if parsed_args.use_default_subnet_pool:
+            attrs['use_default_subnetpool'] = True
+        if parsed_args.prefix_length is not None:
+            attrs['prefixlen'] = parsed_args.prefix_length
+        if parsed_args.subnet_range is not None:
+            attrs['cidr'] = parsed_args.subnet_range
+        if parsed_args.ip_version is not None:
+            attrs['ip_version'] = parsed_args.ip_version
+        if parsed_args.ipv6_ra_mode is not None:
+            attrs['ipv6_ra_mode'] = parsed_args.ipv6_ra_mode
+        if parsed_args.ipv6_address_mode is not None:
+            attrs['ipv6_address_mode'] = parsed_args.ipv6_address_mode
 
-    client = client_manager.network
-    attrs['network_id'] = client.find_network(parsed_args.network,
-                                              ignore_missing=False).id
+    if 'gateway' in parsed_args and parsed_args.gateway is not None:
+        gateway = parsed_args.gateway.lower()
 
-    if parsed_args.subnet_pool is not None:
-        subnet_pool = client.find_subnet_pool(parsed_args.subnet_pool,
-                                              ignore_missing=False)
-        attrs['subnetpool_id'] = subnet_pool.id
-
-    if parsed_args.use_default_subnet_pool:
-        attrs['use_default_subnetpool'] = True
-    if parsed_args.gateway.lower() != 'auto':
-        if parsed_args.gateway.lower() == 'none':
-            attrs['gateway_ip'] = None
-        else:
-            attrs['gateway_ip'] = parsed_args.gateway
-    if parsed_args.prefix_length is not None:
-        attrs['prefixlen'] = parsed_args.prefix_length
-    if parsed_args.subnet_range is not None:
-        attrs['cidr'] = parsed_args.subnet_range
-    if parsed_args.ip_version is not None:
-        attrs['ip_version'] = parsed_args.ip_version
-    if parsed_args.ipv6_ra_mode is not None:
-        attrs['ipv6_ra_mode'] = parsed_args.ipv6_ra_mode
-    if parsed_args.ipv6_address_mode is not None:
-        attrs['ipv6_address_mode'] = parsed_args.ipv6_address_mode
-    if parsed_args.allocation_pools is not None:
+        if not is_create and gateway == 'auto':
+            raise exceptions.CommandError("Auto option is not available"
+                                          " for Subnet Set. Valid options are"
+                                          " <ip-address> or none")
+        elif gateway != 'auto':
+            if gateway == 'none':
+                attrs['gateway_ip'] = None
+            else:
+                attrs['gateway_ip'] = gateway
+    if ('allocation_pools' in parsed_args and
+       parsed_args.allocation_pools is not None):
         attrs['allocation_pools'] = parsed_args.allocation_pools
-    if parsed_args.enable_dhcp is not None:
-        attrs['enable_dhcp'] = parsed_args.enable_dhcp
-    if parsed_args.dns_nameservers is not None:
+    if parsed_args.dhcp:
+        attrs['enable_dhcp'] = True
+    elif parsed_args.no_dhcp:
+        attrs['enable_dhcp'] = False
+    if ('dns_nameservers' in parsed_args and
+       parsed_args.dns_nameservers is not None):
         attrs['dns_nameservers'] = parsed_args.dns_nameservers
-    if parsed_args.host_routes is not None:
+    if 'host_routes' in parsed_args and parsed_args.host_routes is not None:
         # Change 'gateway' entry to 'nexthop' to match the API
         attrs['host_routes'] = convert_entries_to_nexthop(
             parsed_args.host_routes)
-
     return attrs
 
 
@@ -163,38 +206,18 @@ class CreateSubnet(command.ShowOne):
                  '(required if --subnet-pool is not specified, '
                  'optional otherwise)',
         )
-        parser.add_argument(
-            '--allocation-pool',
-            metavar='start=<ip-address>,end=<ip-address>',
-            dest='allocation_pools',
-            action=parseractions.MultiKeyValueAction,
-            required_keys=['start', 'end'],
-            help='Allocation pool IP addresses for this subnet '
-                 'e.g.: start=192.168.199.2,end=192.168.199.254 '
-                 '(This option can be repeated)',
-        )
         dhcp_enable_group = parser.add_mutually_exclusive_group()
         dhcp_enable_group.add_argument(
             '--dhcp',
-            dest='enable_dhcp',
             action='store_true',
             default=True,
             help='Enable DHCP (default)',
         )
         dhcp_enable_group.add_argument(
             '--no-dhcp',
-            dest='enable_dhcp',
-            action='store_false',
+            action='store_true',
             help='Disable DHCP',
         )
-        parser.add_argument(
-            '--dns-nameserver',
-            metavar='<dns-nameserver>',
-            action='append',
-            dest='dns_nameservers',
-            help='DNS name server for this subnet '
-                 '(This option can be repeated)',
-        )
         parser.add_argument(
             '--gateway',
             metavar='<gateway>',
@@ -207,18 +230,6 @@ class CreateSubnet(command.ShowOne):
                  "e.g.: --gateway 192.168.9.1, --gateway auto, --gateway none"
                  "(default is 'auto')",
         )
-        parser.add_argument(
-            '--host-route',
-            metavar='destination=<subnet>,gateway=<ip-address>',
-            dest='host_routes',
-            action=parseractions.MultiKeyValueAction,
-            required_keys=['destination', 'gateway'],
-            help='Additional route for this subnet '
-                 'e.g.: destination=10.10.0.0/16,gateway=192.168.71.254 '
-                 'destination: destination subnet (in CIDR notation) '
-                 'gateway: nexthop IP address '
-                 '(This option can be repeated)',
-        )
         parser.add_argument(
             '--ip-version',
             type=int,
@@ -246,7 +257,7 @@ class CreateSubnet(command.ShowOne):
             metavar='<network>',
             help='Network this subnet belongs to (name or ID)',
         )
-
+        _get_common_parse_arguments(parser)
         return parser
 
     def take_action(self, parsed_args):
@@ -309,6 +320,56 @@ class ListSubnet(command.Lister):
                 ) for s in data))
 
 
+class SetSubnet(command.Command):
+    """Set subnet properties"""
+
+    def get_parser(self, prog_name):
+        parser = super(SetSubnet, self).get_parser(prog_name)
+        parser.add_argument(
+            'subnet',
+            metavar="<subnet>",
+            help=("Subnet to modify (name or ID)")
+        )
+        parser.add_argument(
+            '--name',
+            metavar='<name>',
+            help='Updated name of the subnet',
+        )
+        dhcp_enable_group = parser.add_mutually_exclusive_group()
+        dhcp_enable_group.add_argument(
+            '--dhcp',
+            action='store_true',
+            default=None,
+            help='Enable DHCP',
+        )
+        dhcp_enable_group.add_argument(
+            '--no-dhcp',
+            action='store_true',
+            help='Disable DHCP',
+        )
+        parser.add_argument(
+            '--gateway',
+            metavar='<gateway>',
+            help="Specify a gateway for the subnet. The options are: "
+                 "  <ip-address>: Specific IP address to use as the gateway "
+                 "  'none':       This subnet will not use a gateway "
+                 "e.g.: --gateway 192.168.9.1, --gateway none"
+        )
+        _get_common_parse_arguments(parser)
+        return parser
+
+    def take_action(self, parsed_args):
+        client = self.app.client_manager.network
+        obj = client.find_subnet(parsed_args.subnet, ignore_missing=False)
+        attrs = _get_attrs(self.app.client_manager, parsed_args,
+                           is_create=False)
+        if not attrs:
+            msg = "Nothing specified to be set"
+            raise exceptions.CommandError(msg)
+        client.update_subnet(obj, **attrs)
+        return
+
+
 class ShowSubnet(command.ShowOne):
     """Show subnet details"""
 
diff --git a/openstackclient/tests/network/v2/test_subnet.py b/openstackclient/tests/network/v2/test_subnet.py
index de17c78922..2535bbe6d8 100644
--- a/openstackclient/tests/network/v2/test_subnet.py
+++ b/openstackclient/tests/network/v2/test_subnet.py
@@ -14,6 +14,7 @@
 import copy
 import mock
 
+from openstackclient.common import exceptions
 from openstackclient.common import utils
 from openstackclient.network.v2 import subnet as subnet_v2
 from openstackclient.tests import fakes
@@ -203,9 +204,9 @@ class TestCreateSubnet(TestSubnet):
         self.network.find_network = mock.Mock(return_value=self._network)
 
         arglist = [
-            self._subnet.name,
             "--subnet-range", self._subnet.cidr,
             "--network", self._subnet.network_id,
+            self._subnet.name,
         ]
         verifylist = [
             ('name', self._subnet.name),
@@ -266,7 +267,7 @@ class TestCreateSubnet(TestSubnet):
             ('ip_version', self._subnet_from_pool.ip_version),
             ('gateway', self._subnet_from_pool.gateway_ip),
             ('dns_nameservers', self._subnet_from_pool.dns_nameservers),
-            ('enable_dhcp', self._subnet_from_pool.enable_dhcp),
+            ('dhcp', self._subnet_from_pool.enable_dhcp),
             ('host_routes', subnet_v2.convert_entries_to_gateway(
                 self._subnet_from_pool.host_routes)),
             ('subnet_pool', self._subnet_from_pool.subnetpool_id),
@@ -332,7 +333,7 @@ class TestCreateSubnet(TestSubnet):
             ('ipv6_address_mode', self._subnet_ipv6.ipv6_address_mode),
             ('gateway', self._subnet_ipv6.gateway_ip),
             ('dns_nameservers', self._subnet_ipv6.dns_nameservers),
-            ('enable_dhcp', self._subnet_ipv6.enable_dhcp),
+            ('dhcp', self._subnet_ipv6.enable_dhcp),
             ('host_routes', subnet_v2.convert_entries_to_gateway(
                 self._subnet_ipv6.host_routes)),
             ('allocation_pools', self._subnet_ipv6.allocation_pools),
@@ -469,6 +470,73 @@ class TestListSubnet(TestSubnet):
         self.assertEqual(self.data_long, list(data))
 
 
+class TestSetSubnet(TestSubnet):
+
+    _subnet = network_fakes.FakeSubnet.create_one_subnet()
+
+    def setUp(self):
+        super(TestSetSubnet, self).setUp()
+        self.network.update_subnet = mock.Mock(return_value=None)
+        self.network.find_subnet = mock.Mock(return_value=self._subnet)
+        self.cmd = subnet_v2.SetSubnet(self.app, self.namespace)
+
+    def test_set_this(self):
+        arglist = [
+            "--name", "new_subnet",
+            "--dhcp",
+            "--gateway", self._subnet.gateway_ip,
+            self._subnet.name,
+        ]
+        verifylist = [
+            ('name', "new_subnet"),
+            ('dhcp', True),
+            ('gateway', self._subnet.gateway_ip),
+            ('subnet', self._subnet.name),
+        ]
+
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        result = self.cmd.take_action(parsed_args)
+        attrs = {
+            'enable_dhcp': True,
+            'gateway_ip': self._subnet.gateway_ip,
+            'name': "new_subnet",
+        }
+        self.network.update_subnet.assert_called_with(self._subnet, **attrs)
+        self.assertIsNone(result)
+
+    def test_set_that(self):
+        arglist = [
+            "--name", "new_subnet",
+            "--no-dhcp",
+            "--gateway", "none",
+            self._subnet.name,
+        ]
+        verifylist = [
+            ('name', "new_subnet"),
+            ('no_dhcp', True),
+            ('gateway', "none"),
+            ('subnet', self._subnet.name),
+        ]
+
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        result = self.cmd.take_action(parsed_args)
+        attrs = {
+            'enable_dhcp': False,
+            'gateway_ip': None,
+            'name': "new_subnet",
+        }
+        self.network.update_subnet.assert_called_with(self._subnet, **attrs)
+        self.assertIsNone(result)
+
+    def test_set_nothing(self):
+        arglist = [self._subnet.name, ]
+        verifylist = [('subnet', self._subnet.name)]
+
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        self.assertRaises(exceptions.CommandError, self.cmd.take_action,
+                          parsed_args)
+
+
 class TestShowSubnet(TestSubnet):
     # The subnets to be shown
     _subnet = network_fakes.FakeSubnet.create_one_subnet()
diff --git a/releasenotes/notes/subnet-set-bbc26ecc16929302.yaml b/releasenotes/notes/subnet-set-bbc26ecc16929302.yaml
new file mode 100644
index 0000000000..8fb0c3275b
--- /dev/null
+++ b/releasenotes/notes/subnet-set-bbc26ecc16929302.yaml
@@ -0,0 +1,5 @@
+---
+features:
+  - |
+    Add ``subnet set`` command.
+    [Bug `1542363 <https://bugs.launchpad.net/bugs/1542363>`_]
diff --git a/setup.cfg b/setup.cfg
index 0ec5f4c166..5c468cfcde 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -355,6 +355,7 @@ openstack.network.v2 =
     subnet_create = openstackclient.network.v2.subnet:CreateSubnet
     subnet_delete = openstackclient.network.v2.subnet:DeleteSubnet
     subnet_list = openstackclient.network.v2.subnet:ListSubnet
+    subnet_set = openstackclient.network.v2.subnet:SetSubnet
     subnet_show = openstackclient.network.v2.subnet:ShowSubnet
 
     subnet_pool_create = openstackclient.network.v2.subnet_pool:CreateSubnetPool