diff --git a/doc/source/command-objects/network-agent.rst b/doc/source/command-objects/network-agent.rst
index 947e07cf6c..d764f3de1c 100644
--- a/doc/source/command-objects/network-agent.rst
+++ b/doc/source/command-objects/network-agent.rst
@@ -10,6 +10,31 @@ agent is "True".
 
 Network v2
 
+network agent add network
+-------------------------
+
+Add network to an agent
+
+.. program:: network agent add network
+.. code:: bash
+
+    openstack network agent add network
+        [--dhcp]
+        <agent-id>
+        <network>
+
+.. describe:: --dhcp
+
+    Add a network to DHCP agent.
+
+.. describe:: <agent-id>
+
+    Agent to which a network is added. (ID only)
+
+.. describe:: <network>
+
+    Network to be added to an agent. (ID or name)
+
 network agent delete
 --------------------
 
@@ -37,6 +62,7 @@ List network agents
     openstack network agent list
         [--agent-type <agent-type>]
         [--host <host>]
+        [--network <network>]
 
 .. option:: --agent-type <agent-type>
 
@@ -49,6 +75,10 @@ List network agents
 
     List only agents running on the specified host
 
+.. option:: --network <network>
+
+    List agents hosting a network. (ID or name)
+
 network agent set
 -----------------
 
@@ -94,3 +124,28 @@ Display network agent details
 .. describe:: <network-agent>
 
     Network agent to display (ID only)
+
+network agent remove network
+----------------------------
+
+Remove network from an agent
+
+.. program:: network agent remove network
+.. code:: bash
+
+    openstack network agent remove network
+        [--dhcp]
+        <agent-id>
+        <network>
+
+.. describe:: --dhcp
+
+    Remove network from DHCP agent.
+
+.. describe:: <agent-id>
+
+    Agent to which a network is removed. (ID only)
+
+.. describe:: <network>
+
+    Network to be removed from an agent. (ID or name)
diff --git a/doc/source/command-objects/network.rst b/doc/source/command-objects/network.rst
index dc597443ce..9162dbff01 100644
--- a/doc/source/command-objects/network.rst
+++ b/doc/source/command-objects/network.rst
@@ -203,6 +203,7 @@ List networks
         [--provider-network-type <provider-network-type>]
         [--provider-physical-network <provider-physical-network>]
         [--provider-segment <provider-segment>]
+        [--agent <agent-id>]
 
 .. option:: --external
 
@@ -290,6 +291,10 @@ List networks
 
     *Network version 2 only*
 
+.. option:: --agent <agent-id>
+
+    List networks hosted by agent (ID only)
+
 network set
 -----------
 
diff --git a/openstackclient/network/v2/network.py b/openstackclient/network/v2/network.py
index 3aa8ec8442..3e0bb7764b 100644
--- a/openstackclient/network/v2/network.py
+++ b/openstackclient/network/v2/network.py
@@ -60,12 +60,10 @@ def _get_network_columns(item):
 
 
 def _get_columns(item):
-    columns = list(item.keys())
-    if 'tenant_id' in columns:
-        columns.remove('tenant_id')
-    if 'project_id' not in columns:
-        columns.append('project_id')
-    return tuple(sorted(columns))
+    column_map = {
+        'tenant_id': 'project_id',
+    }
+    return sdk_utils.get_osc_show_columns_for_sdk_resource(item, column_map)
 
 
 def _get_attrs(client_manager, parsed_args):
@@ -305,9 +303,9 @@ class CreateNetwork(common.NetworkAndComputeShowOne):
     def take_action_compute(self, client, parsed_args):
         attrs = _get_attrs_compute(self.app.client_manager, parsed_args)
         obj = client.networks.create(**attrs)
-        columns = _get_columns(obj._info)
+        display_columns, columns = _get_columns(obj._info)
         data = utils.get_dict_properties(obj._info, columns)
-        return (columns, data)
+        return (display_columns, data)
 
 
 class DeleteNetwork(common.NetworkAndComputeDelete):
@@ -420,7 +418,11 @@ class ListNetwork(common.NetworkAndComputeLister):
             help=_("List networks according to VLAN ID for VLAN networks "
                    "or Tunnel ID for GENEVE/GRE/VXLAN networks")
         )
-
+        parser.add_argument(
+            '--agent',
+            metavar='<agent-id>',
+            dest='agent_id',
+            help=_('List networks hosted by agent (ID only)'))
         return parser
 
     def take_action_network(self, client, parsed_args):
@@ -450,6 +452,26 @@ class ListNetwork(common.NetworkAndComputeLister):
                 'Router Type',
                 'Availability Zones',
             )
+        elif parsed_args.agent_id:
+            columns = (
+                'id',
+                'name',
+                'subnet_ids'
+            )
+            column_headers = (
+                'ID',
+                'Name',
+                'Subnets',
+            )
+            client = self.app.client_manager.network
+            dhcp_agent = client.get_agent(parsed_args.agent_id)
+            data = client.dhcp_agent_hosting_networks(dhcp_agent)
+
+            return (column_headers,
+                    (utils.get_item_properties(
+                        s, columns,
+                        formatters=_formatters,
+                    ) for s in data))
         else:
             columns = (
                 'id',
@@ -665,6 +687,6 @@ class ShowNetwork(common.NetworkAndComputeShowOne):
             client.networks,
             parsed_args.network,
         )
-        columns = _get_columns(obj._info)
+        display_columns, columns = _get_columns(obj._info)
         data = utils.get_dict_properties(obj._info, columns)
-        return (columns, data)
+        return (display_columns, data)
diff --git a/openstackclient/network/v2/network_agent.py b/openstackclient/network/v2/network_agent.py
index d429fa0830..c23d3e8bb6 100644
--- a/openstackclient/network/v2/network_agent.py
+++ b/openstackclient/network/v2/network_agent.py
@@ -29,7 +29,6 @@ LOG = logging.getLogger(__name__)
 def _format_admin_state(state):
     return 'UP' if state else 'DOWN'
 
-
 _formatters = {
     'admin_state_up': _format_admin_state,
     'is_admin_state_up': _format_admin_state,
@@ -45,6 +44,40 @@ def _get_network_columns(item):
     return sdk_utils.get_osc_show_columns_for_sdk_resource(item, column_map)
 
 
+class AddNetworkToAgent(command.Command):
+    _description = _("Add network to an agent")
+
+    def get_parser(self, prog_name):
+        parser = super(AddNetworkToAgent, self).get_parser(prog_name)
+        parser.add_argument(
+            '--dhcp',
+            action='store_true',
+            help=_('Add network to a DHCP agent'))
+        parser.add_argument(
+            'agent_id',
+            metavar='<agent-id>',
+            help=_('Agent to which a network is added. (ID only)'))
+        parser.add_argument(
+            'network',
+            metavar='<network>',
+            help=_('Network to be added to an agent.  (ID or name)'))
+
+        return parser
+
+    def take_action(self, parsed_args):
+        client = self.app.client_manager.network
+        agent = client.get_agent(parsed_args.agent_id)
+        if parsed_args.dhcp:
+            network = client.find_network(
+                parsed_args.network, ignore_missing=False)
+            try:
+                client.add_dhcp_agent_to_network(agent, network)
+            except Exception:
+                msg = 'Failed to add {} to {}'.format(
+                    network.name, agent.agent_type)
+                exceptions.CommandError(msg)
+
+
 class DeleteNetworkAgent(command.Command):
     _description = _("Delete network agent(s)")
 
@@ -101,6 +134,11 @@ class ListNetworkAgent(command.Lister):
             metavar='<host>',
             help=_("List only agents running on the specified host")
         )
+        parser.add_argument(
+            '--network',
+            metavar='<network>',
+            help=_('List agents hosting a network (name or ID)')
+        )
         return parser
 
     def take_action(self, parsed_args):
@@ -138,16 +176,72 @@ class ListNetworkAgent(command.Lister):
         }
 
         filters = {}
-        if parsed_args.agent_type is not None:
-            filters['agent_type'] = key_value[parsed_args.agent_type]
-        if parsed_args.host is not None:
-            filters['host'] = parsed_args.host
+        if parsed_args.network is not None:
+            columns = (
+                'id',
+                'host',
+                'is_admin_state_up',
+                'is_alive',
+            )
+            column_headers = (
+                'ID',
+                'Host',
+                'Admin State Up',
+                'Alive',
+            )
+            network = client.find_network(
+                parsed_args.network, ignore_missing=False)
+            data = client.network_hosting_dhcp_agents(network)
 
-        data = client.agents(**filters)
-        return (column_headers,
-                (utils.get_item_properties(
-                    s, columns, formatters=_formatters,
-                ) for s in data))
+            return (column_headers,
+                    (utils.get_item_properties(
+                        s, columns,
+                        formatters=_formatters,
+                    ) for s in data))
+        else:
+            if parsed_args.agent_type is not None:
+                filters['agent_type'] = key_value[parsed_args.agent_type]
+            if parsed_args.host is not None:
+                filters['host'] = parsed_args.host
+
+            data = client.agents(**filters)
+            return (column_headers,
+                    (utils.get_item_properties(
+                        s, columns, formatters=_formatters,
+                    ) for s in data))
+
+
+class RemoveNetworkFromAgent(command.Command):
+    _description = _("Remove network from an agent.")
+
+    def get_parser(self, prog_name):
+        parser = super(RemoveNetworkFromAgent, self).get_parser(prog_name)
+        parser.add_argument(
+            '--dhcp',
+            action='store_true',
+            help=_('Remove network from DHCP agent'))
+        parser.add_argument(
+            'agent_id',
+            metavar='<agent-id>',
+            help=_('Agent to which a network is removed. (ID only)'))
+        parser.add_argument(
+            'network',
+            metavar='<network>',
+            help=_('Network to be removed from an agent. (ID or name)'))
+        return parser
+
+    def take_action(self, parsed_args):
+        client = self.app.client_manager.network
+        agent = client.get_agent(parsed_args.agent_id)
+        if parsed_args.dhcp:
+            network = client.find_network(
+                parsed_args.network, ignore_missing=False)
+            try:
+                client.remove_dhcp_agent_from_network(agent, network)
+            except Exception:
+                msg = 'Failed to remove {} to {}'.format(
+                    network.name, agent.agent_type)
+                exceptions.CommandError(msg)
 
 
 # TODO(huanxuan): Use the SDK resource mapped attribute names once the
diff --git a/openstackclient/tests/functional/network/v2/test_network.py b/openstackclient/tests/functional/network/v2/test_network.py
index 126365581a..0e10bfce1a 100644
--- a/openstackclient/tests/functional/network/v2/test_network.py
+++ b/openstackclient/tests/functional/network/v2/test_network.py
@@ -238,6 +238,49 @@ class NetworkTests(base.TestCase):
         self.assertIn(name1, col_name)
         self.assertNotIn(name2, col_name)
 
+    def test_network_dhcp_agent(self):
+        name1 = uuid.uuid4().hex
+        cmd_output1 = json.loads(self.openstack(
+            'network create -f json ' +
+            '--description aaaa ' +
+            name1
+        ))
+
+        self.addCleanup(self.openstack, 'network delete ' + name1)
+
+        # Get network ID
+        network_id = cmd_output1['id']
+
+        # Get DHCP Agent ID
+        cmd_output2 = json.loads(self.openstack(
+            'network agent list -f json --agent-type dhcp'
+        ))
+        agent_id = cmd_output2[0]['ID']
+
+        # Add Agent to Network
+        self.openstack(
+            'network agent add network --dhcp '
+            + agent_id + ' ' + network_id
+        )
+
+        # Test network list --agent
+        cmd_output3 = json.loads(self.openstack(
+            'network list -f json --agent ' + agent_id
+        ))
+
+        # Cleanup
+        # Remove Agent from Network
+        self.openstack(
+            'network agent remove network --dhcp '
+            + agent_id + ' ' + network_id
+        )
+
+        # Assert
+        col_name = [x["ID"] for x in cmd_output3]
+        self.assertIn(
+            network_id, col_name
+        )
+
     def test_network_set(self):
         """Tests create options, set, show, delete"""
         name = uuid.uuid4().hex
diff --git a/openstackclient/tests/functional/network/v2/test_network_agent.py b/openstackclient/tests/functional/network/v2/test_network_agent.py
index dd6112e72e..6da721d1e7 100644
--- a/openstackclient/tests/functional/network/v2/test_network_agent.py
+++ b/openstackclient/tests/functional/network/v2/test_network_agent.py
@@ -10,6 +10,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import json
+import uuid
+
 from openstackclient.tests.functional import base
 
 
@@ -39,3 +42,52 @@ class NetworkAgentTests(base.TestCase):
         self.openstack('network agent set --enable ' + self.IDs[0])
         raw_output = self.openstack('network agent show ' + self.IDs[0] + opts)
         self.assertEqual("UP\n", raw_output)
+
+
+class NetworkAgentListTests(base.TestCase):
+    """Functional test for network agent list --network. """
+
+    def test_network_dhcp_agent_list(self):
+        """Test network agent list"""
+
+        name1 = uuid.uuid4().hex
+        cmd_output1 = json.loads(self.openstack(
+            'network create -f json ' +
+            '--description aaaa ' +
+            name1
+        ))
+
+        self.addCleanup(self.openstack, 'network delete ' + name1)
+
+        # Get network ID
+        network_id = cmd_output1['id']
+
+        # Get DHCP Agent ID
+        cmd_output2 = json.loads(self.openstack(
+            'network agent list -f json --agent-type dhcp'
+        ))
+        agent_id = cmd_output2[0]['ID']
+
+        # Add Agent to Network
+        self.openstack(
+            'network agent add network --dhcp '
+            + agent_id + ' ' + network_id
+        )
+
+        # Test network agent list --network
+        cmd_output3 = json.loads(self.openstack(
+            'network agent list -f json --network ' + network_id
+        ))
+
+        # Cleanup
+        # Remove Agent from Network
+        self.openstack(
+            'network agent remove network --dhcp '
+            + agent_id + ' ' + network_id
+        )
+
+        # Assert
+        col_name = [x["ID"] for x in cmd_output3]
+        self.assertIn(
+            agent_id, col_name
+        )
diff --git a/openstackclient/tests/unit/network/v2/test_network.py b/openstackclient/tests/unit/network/v2/test_network.py
index b405bef9a8..bc1279ecbe 100644
--- a/openstackclient/tests/unit/network/v2/test_network.py
+++ b/openstackclient/tests/unit/network/v2/test_network.py
@@ -491,6 +491,13 @@ class TestListNetwork(TestNetwork):
 
         self.network.networks = mock.Mock(return_value=self._network)
 
+        self._agent = \
+            network_fakes.FakeNetworkAgent.create_one_network_agent()
+        self.network.get_agent = mock.Mock(return_value=self._agent)
+
+        self.network.dhcp_agent_hosting_networks = mock.Mock(
+            return_value=self._network)
+
     def test_network_list_no_options(self):
         arglist = []
         verifylist = [
@@ -765,6 +772,25 @@ class TestListNetwork(TestNetwork):
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, list(data))
 
+    def test_network_list_dhcp_agent(self):
+        arglist = [
+            '--agent', self._agent.id
+        ]
+        verifylist = [
+            ('agent_id', self._agent.id),
+        ]
+
+        attrs = {self._agent, }
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = self.cmd.take_action(parsed_args)
+
+        self.network.dhcp_agent_hosting_networks.assert_called_once_with(
+            *attrs)
+
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(list(data), list(self.data))
+
 
 class TestSetNetwork(TestNetwork):
 
diff --git a/openstackclient/tests/unit/network/v2/test_network_agent.py b/openstackclient/tests/unit/network/v2/test_network_agent.py
index 2fc0c04328..0d741e06a9 100644
--- a/openstackclient/tests/unit/network/v2/test_network_agent.py
+++ b/openstackclient/tests/unit/network/v2/test_network_agent.py
@@ -31,6 +31,48 @@ class TestNetworkAgent(network_fakes.TestNetworkV2):
         self.network = self.app.client_manager.network
 
 
+class TestAddNetworkToAgent(TestNetworkAgent):
+
+    net = network_fakes.FakeNetwork.create_one_network()
+    agent = network_fakes.FakeNetworkAgent.create_one_network_agent()
+
+    def setUp(self):
+        super(TestAddNetworkToAgent, self).setUp()
+
+        self.network.get_agent = mock.Mock(return_value=self.agent)
+        self.network.find_network = mock.Mock(return_value=self.net)
+        self.network.name = self.network.find_network.name
+        self.network.add_dhcp_agent_to_network = mock.Mock()
+        self.cmd = network_agent.AddNetworkToAgent(
+            self.app, self.namespace)
+
+    def test_show_no_options(self):
+        arglist = []
+        verifylist = []
+
+        # Missing required args should bail here
+        self.assertRaises(tests_utils.ParserException, self.check_parser,
+                          self.cmd, arglist, verifylist)
+
+    def test_add_network_to_dhcp_agent(self):
+        arglist = [
+            '--dhcp',
+            self.agent.id,
+            self.net.id
+        ]
+        verifylist = [
+            ('dhcp', True),
+            ('agent_id', self.agent.id),
+            ('network', self.net.id),
+        ]
+
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        self.cmd.take_action(parsed_args)
+
+        self.network.add_dhcp_agent_to_network.assert_called_once_with(
+            self.agent, self.net)
+
+
 class TestDeleteNetworkAgent(TestNetworkAgent):
 
     network_agents = (
@@ -66,7 +108,6 @@ class TestDeleteNetworkAgent(TestNetworkAgent):
 
     def test_multi_network_agents_delete(self):
         arglist = []
-        verifylist = []
 
         for n in self.network_agents:
             arglist.append(n.id)
@@ -141,11 +182,37 @@ class TestListNetworkAgent(TestNetworkAgent):
             agent.binary,
         ))
 
+    network_agent_columns = (
+        'ID',
+        'Host',
+        'Admin State Up',
+        'Alive',
+    )
+
+    network_agent_data = []
+
+    for agent in network_agents:
+        network_agent_data.append((
+            agent.id,
+            agent.host,
+            network_agent._format_admin_state(agent.admin_state_up),
+            agent.alive,
+        ))
+
     def setUp(self):
         super(TestListNetworkAgent, self).setUp()
         self.network.agents = mock.Mock(
             return_value=self.network_agents)
 
+        _testagent = \
+            network_fakes.FakeNetworkAgent.create_one_network_agent()
+        self.network.get_agent = mock.Mock(return_value=_testagent)
+
+        self._testnetwork = network_fakes.FakeNetwork.create_one_network()
+        self.network.find_network = mock.Mock(return_value=self._testnetwork)
+        self.network.network_hosting_dhcp_agents = mock.Mock(
+            return_value=self.network_agents)
+
         # Get the command object to test
         self.cmd = network_agent.ListNetworkAgent(self.app, self.namespace)
 
@@ -194,6 +261,66 @@ class TestListNetworkAgent(TestNetworkAgent):
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.data, list(data))
 
+    def test_network_agents_list_networks(self):
+        arglist = [
+            '--network', self._testnetwork.id,
+        ]
+        verifylist = [
+            ('network', self._testnetwork.id),
+        ]
+
+        attrs = {self._testnetwork, }
+
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        columns, data = self.cmd.take_action(parsed_args)
+
+        self.network.network_hosting_dhcp_agents.assert_called_once_with(
+            *attrs)
+        self.assertEqual(self.network_agent_columns, columns)
+        self.assertEqual(list(self.network_agent_data), list(data))
+
+
+class TestRemoveNetworkFromAgent(TestNetworkAgent):
+
+    net = network_fakes.FakeNetwork.create_one_network()
+    agent = network_fakes.FakeNetworkAgent.create_one_network_agent()
+
+    def setUp(self):
+        super(TestRemoveNetworkFromAgent, self).setUp()
+
+        self.network.get_agent = mock.Mock(return_value=self.agent)
+        self.network.find_network = mock.Mock(return_value=self.net)
+        self.network.name = self.network.find_network.name
+        self.network.remove_dhcp_agent_from_network = mock.Mock()
+        self.cmd = network_agent.RemoveNetworkFromAgent(
+            self.app, self.namespace)
+
+    def test_show_no_options(self):
+        arglist = []
+        verifylist = []
+
+        # Missing required args should bail here
+        self.assertRaises(tests_utils.ParserException, self.check_parser,
+                          self.cmd, arglist, verifylist)
+
+    def test_network_from_dhcp_agent(self):
+        arglist = [
+            '--dhcp',
+            self.agent.id,
+            self.net.id
+        ]
+        verifylist = [
+            ('dhcp', True),
+            ('agent_id', self.agent.id),
+            ('network', self.net.id),
+        ]
+
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        self.cmd.take_action(parsed_args)
+
+        self.network.remove_dhcp_agent_from_network.assert_called_once_with(
+            self.agent, self.net)
+
 
 # TODO(huanxuan): Also update by the new attribute name
 # "is_admin_state_up" after sdk 0.9.12
diff --git a/releasenotes/notes/bp-network-dhcp-adv-commands-e61bf8757f46dc93.yaml b/releasenotes/notes/bp-network-dhcp-adv-commands-e61bf8757f46dc93.yaml
new file mode 100644
index 0000000000..ce3ab644f4
--- /dev/null
+++ b/releasenotes/notes/bp-network-dhcp-adv-commands-e61bf8757f46dc93.yaml
@@ -0,0 +1,7 @@
+---
+features:
+  - |
+    Add network dhcp-agent related commands ``network agent add network``,
+    ``network agent remove network``, ``network agent list --network`` and
+    ``network list --agent`` for adding/removing network to dhcp agent.
+    [Blueprint :oscbp:`network-dhcp-adv-commands`]
diff --git a/setup.cfg b/setup.cfg
index e18aa5c1e7..7ebe624a3f 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -355,8 +355,10 @@ openstack.network.v2 =
 
     ip_floating_pool_list = openstackclient.network.v2.floating_ip_pool:ListIPFloatingPool
 
+    network_agent_add_network = openstackclient.network.v2.network_agent:AddNetworkToAgent
     network_agent_delete = openstackclient.network.v2.network_agent:DeleteNetworkAgent
     network_agent_list = openstackclient.network.v2.network_agent:ListNetworkAgent
+    network_agent_remove_network = openstackclient.network.v2.network_agent:RemoveNetworkFromAgent
     network_agent_set = openstackclient.network.v2.network_agent:SetNetworkAgent
     network_agent_show = openstackclient.network.v2.network_agent:ShowNetworkAgent