diff --git a/rsd_lib/resources/v2_1/fabric/port.py b/rsd_lib/resources/v2_1/fabric/port.py
new file mode 100644
index 0000000..e783ec2
--- /dev/null
+++ b/rsd_lib/resources/v2_1/fabric/port.py
@@ -0,0 +1,138 @@
+# Copyright 2019 Intel, Inc.
+# All Rights Reserved.
+#
+#    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 logging
+
+from sushy.resources import base
+
+from sushy import utils
+
+LOG = logging.getLogger(__name__)
+
+
+class StatusField(base.CompositeField):
+    state = base.Field("State")
+    """The status state"""
+
+    health = base.Field("Health")
+    """The status health"""
+
+
+class PortResetField(base.CompositeField):
+    target = base.Field("target")
+    """The port reset target"""
+
+    reset_type_redfish_allowable_values = base.Field("ResetType@Redfish."
+                                                     "AllowableValues")
+    """The port reset type redfish allowable values"""
+
+
+class ActionsField(base.CompositeField):
+    port_reset = PortResetField("#Port.Reset")
+    """The action port reset"""
+
+
+class LinksField(base.CompositeField):
+    associated_endpoints = base.Field("AssociatedEndpoints", default=[],
+                                      adapter=utils.get_members_identities)
+    """The link associated endpoints"""
+
+
+class IntelRackScaleField(base.CompositeField):
+    odata_type = base.Field("@odata.type")
+    """The Intel Rack Scale odata type"""
+
+    pcie_connection_id = base.Field("PCIeConnectionId")
+    """The Intel Rack Scale PCIe Connection Id"""
+
+
+class OemField(base.CompositeField):
+    intel_rackScale = IntelRackScaleField("Intel_RackScale")
+    """The oem intel rack scale"""
+
+
+class Port(base.ResourceBase):
+    identity = base.Field("Id")
+    """The port identity string"""
+
+    name = base.Field("Name")
+    """The port name"""
+
+    description = base.Field("Description")
+    """The port description"""
+
+    status = StatusField("Status")
+    """The port status"""
+
+    port_id = base.Field("PortId")
+    """The port id"""
+
+    port_protocol = base.Field("PortProtocol")
+    """The port protocol"""
+
+    port_type = base.Field("PortType")
+    """The port type"""
+
+    current_speed_gbps = base.Field("CurrentSpeedGbps")
+    """The port current speed Gbps"""
+
+    width = base.Field("Width")
+    """The port width"""
+
+    max_speed_gbps = base.Field("MaxSpeedGbps")
+    """The port max speed gbps"""
+
+    actions = ActionsField("Actions")
+    """The port actions"""
+
+    oem = OemField("Oem")
+    """The port oem"""
+
+    links = LinksField("Links")
+    """The port links"""
+
+    def __init__(self, connector, identity, redfish_version=None):
+        """A class representing a Port
+
+        :param connector: A Connector instance
+        :param identity: The identity of the Port resource
+        :param redfish_version: The version of RedFish. Used to construct
+            the object according to schema of the given version.
+        """
+        super(Port, self).__init__(connector, identity,
+                                   redfish_version)
+
+    def reset_port(self):
+        """A post method to reset port"""
+
+        data = {"ResetType": "ForceRestart"}
+        target_uri = self.actions.port_reset.target
+        self._conn.post(target_uri, data=data)
+
+
+class PortCollection(base.ResourceCollectionBase):
+    @property
+    def _resource_type(self):
+        return Port
+
+    def __init__(self, connector, path, redfish_version=None):
+        """A class representing a Port
+
+        :param connector: A Connector instance
+        :param path: The canonical path to the Port collection resource
+        :param redfish_version: The version of RedFish. Used to construct
+            the object according to schema of the given version.
+        """
+        super(PortCollection, self).__init__(connector, path, redfish_version)
diff --git a/rsd_lib/resources/v2_1/fabric/switch.py b/rsd_lib/resources/v2_1/fabric/switch.py
index bcc9521..46ce1bd 100644
--- a/rsd_lib/resources/v2_1/fabric/switch.py
+++ b/rsd_lib/resources/v2_1/fabric/switch.py
@@ -14,10 +14,10 @@
 #    under the License.
 
 import logging
-
 from sushy.resources import base
 from sushy import utils
 
+from rsd_lib.resources.v2_1.fabric import port
 from rsd_lib import utils as rsd_lib_utils
 
 LOG = logging.getLogger(__name__)
@@ -29,10 +29,6 @@ class StatusField(base.CompositeField):
     health_rollup = base.Field('HealthRollUp')
 
 
-class PortsField(base.CompositeField):
-    identity = base.Field('@odata.id')
-
-
 class LinksField(base.CompositeField):
     chassis = base.Field("Chassis", adapter=utils.get_members_identities)
 
@@ -101,9 +97,6 @@ class Switch(base.ResourceBase):
     power_state = base.Field('PowerState')
     """The switch power state"""
 
-    ports = PortsField('Ports')
-    """The switch ports"""
-
     links = LinksField("Links")
     """The switch links"""
 
@@ -122,14 +115,28 @@ class Switch(base.ResourceBase):
                                      redfish_version)
 
     def reset_switch(self):
-        """A post method to reset switch
+        """A post method to reset switch"""
 
-        :returns: The uri of the acl rule
-        """
         data = {"ResetType": "GracefulRestart"}
         target_uri = self.actions.switch_reset.target
         self._conn.post(target_uri, data=data)
 
+    def _get_ports_path(self):
+        """Helper function to find the network protocol path"""
+        return utils.get_sub_resource_path_by(self, 'Ports')
+
+    @property
+    @utils.cache_it
+    def ports(self):
+        """Property to provide reference to ` Ports` instance
+
+        It is calculated once when it is queried for the first time. On
+        refresh, this property is reset.
+        """
+        return port.PortCollection(
+            self._conn, self._get_ports_path(),
+            redfish_version=self.redfish_version)
+
 
 class SwitchCollection(base.ResourceCollectionBase):
 
diff --git a/rsd_lib/tests/unit/json_samples/v2_1/fabrics_port.json b/rsd_lib/tests/unit/json_samples/v2_1/fabrics_port.json
new file mode 100644
index 0000000..75b1f68
--- /dev/null
+++ b/rsd_lib/tests/unit/json_samples/v2_1/fabrics_port.json
@@ -0,0 +1,52 @@
+{
+    "@odata.context":"/redfish/v1/$metadata#Port.Port",
+    "@odata.id":"/redfish/v1/Fabrics/PCIe/Switches/1/Ports/Up1",
+    "@odata.type":"#Port.v1_0_0.Port",
+    "Id":"Up1",
+    "Name":"PCIe Upstream Port 1",
+    "Description":"PCIe Upstream Port 1",
+    "Status":{
+        "State":"Enabled",
+        "Health":"OK"
+    },
+    "PortId":"1",
+    "PortProtocol":"PCIe",
+    "PortType":"UpstreamPort",
+    "CurrentSpeedGbps":32,
+    "Width":4,
+    "MaxSpeedGbps":64,
+    "Actions":{
+        "#Port.Reset":{
+            "target":"/redfish/v1/Fabrics/PCIe/Switches/1/Ports/Up1/Actions/PCIePort.Reset",
+            "ResetType@Redfish.AllowableValues":[
+                "ForceOff",
+                "ForceRestart",
+                "ForceOn"
+            ]
+        },
+        "Oem":{
+
+        }
+    },
+    "Links":{
+        "AssociatedEndpoints":[
+            {
+                "@odata.id":"/redfish/v1/Fabrics/PCIe/Endpoints/HostRootComplex1"
+            }
+        ],
+        "ConnectedSwitches":[
+
+        ],
+        "ConnectedSwitchPorts":[
+
+        ]
+    },
+    "Oem":{
+        "Intel_RackScale":{
+            "@odata.type":"#Intel.Oem.Port",
+            "PCIeConnectionId":[
+                "XYZ1234567890"
+            ]
+        }
+    }
+}
diff --git a/rsd_lib/tests/unit/json_samples/v2_1/fabrics_port_collection.json b/rsd_lib/tests/unit/json_samples/v2_1/fabrics_port_collection.json
new file mode 100644
index 0000000..361ca52
--- /dev/null
+++ b/rsd_lib/tests/unit/json_samples/v2_1/fabrics_port_collection.json
@@ -0,0 +1,22 @@
+{
+    "@odata.context":"/redfish/v1/$metadata#PortCollection.PortCollection",
+    "@odata.id":"/redfish/v1/Fabrics/PCIe/Switches/1/Ports",
+    "@odata.type":"#PortCollection.PortCollection",
+    "Name":"PCIe Port Collection",
+    "Description":"PCIe Port Collection",
+    "Members@odata.count":4,
+    "Members":[
+        {
+            "@odata.id":"/redfish/v1/Fabrics/PCIe/Switches/1/Ports/Up1"
+        },
+        {
+            "@odata.id":"/redfish/v1/Fabrics/PCIe/Switches/1/Ports/Up2"
+        },
+        {
+            "@odata.id":"/redfish/v1/Fabrics/PCIe/Switches/1/Ports/Down1"
+        },
+        {
+            "@odata.id":"/redfish/v1/Fabrics/PCIe/Switches/1/Ports/Down2"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/rsd_lib/tests/unit/resources/v2_1/fabric/test_port.py b/rsd_lib/tests/unit/resources/v2_1/fabric/test_port.py
new file mode 100644
index 0000000..1cf256d
--- /dev/null
+++ b/rsd_lib/tests/unit/resources/v2_1/fabric/test_port.py
@@ -0,0 +1,112 @@
+# Copyright 2019 Intel, Inc.
+# All Rights Reserved.
+#
+#    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 json
+
+import mock
+import testtools
+
+from rsd_lib.resources.v2_1.fabric import port
+
+
+class PortTestCase(testtools.TestCase):
+
+    def setUp(self):
+        super(PortTestCase, self).setUp()
+        self.conn = mock.Mock()
+        with open('rsd_lib/tests/unit/json_samples/v2_1/fabrics_port.json',
+                  'r') as f:
+            self.conn.get.return_value.json.return_value = json.loads(f.read())
+
+        self.port_inst = port.Port(
+            self.conn, '/redfish/v1/Fabrics/PCIe/Switches/1/Ports/Up1',
+            redfish_version='1.0.2')
+
+    def test__parse_attributes(self):
+        self.port_inst._parse_attributes()
+        self.assertEqual("Up1", self.port_inst.identity)
+        self.assertEqual("PCIe Upstream Port 1", self.port_inst.name)
+        self.assertEqual("PCIe Upstream Port 1", self.port_inst.description)
+        self.assertEqual("Enabled", self.port_inst.status.state)
+        self.assertEqual("OK", self.port_inst.status.health)
+        self.assertEqual("1", self.port_inst.port_id)
+        self.assertEqual("PCIe", self.port_inst.port_protocol)
+        self.assertEqual("UpstreamPort", self.port_inst.port_type)
+        self.assertEqual(32, self.port_inst.current_speed_gbps)
+        self.assertEqual(4, self.port_inst.width)
+        self.assertEqual(64, self.port_inst.max_speed_gbps)
+        self.assertEqual("/redfish/v1/Fabrics/PCIe/Switches/1/Ports/Up1"
+                         "/Actions/PCIePort.Reset", self.
+                         port_inst.actions.port_reset.target)
+        self.assertEqual(["ForceOff", "ForceRestart", "ForceOn"],
+                         self.port_inst.actions.port_reset.
+                         reset_type_redfish_allowable_values)
+        self.assertEqual(('/redfish/v1/Fabrics/PCIe/Endpoints/'
+                          'HostRootComplex1',),
+                         self.port_inst.links.associated_endpoints)
+        self.assertEqual("#Intel.Oem.Port",
+                         self.port_inst.oem.intel_rackScale.odata_type)
+        self.assertEqual(['XYZ1234567890'],
+                         self.port_inst.oem.intel_rackScale.pcie_connection_id)
+
+    def test_reset_port(self):
+        self.port_inst.reset_port()
+        self.port_inst._conn.post.assert_called_once_with(
+            '/redfish/v1/Fabrics/PCIe/Switches/1/'
+            'Ports/Up1/Actions/PCIePort.Reset',
+            data={"ResetType": "ForceRestart"})
+
+
+class PortCollectionTestCase(testtools.TestCase):
+
+    def setUp(self):
+        super(PortCollectionTestCase, self).setUp()
+        self.conn = mock.Mock()
+        with open('rsd_lib/tests/unit/json_samples/v2_1/'
+                  'fabrics_port_collection.json', 'r') as f:
+            self.conn.get.return_value.json.return_value = json.loads(f.read())
+        self.port_col = port.PortCollection(
+            self.conn, '/redfish/v1/Fabrics/PCIe/Switches/1/Ports',
+            redfish_version='1.0.2')
+
+    def test__parse_attributes(self):
+        self.port_col._parse_attributes()
+        self.assertEqual("PCIe Port Collection", self.port_col.name)
+        self.assertEqual("1.0.2", self.port_col.redfish_version)
+        self.assertEqual(('/redfish/v1/Fabrics/PCIe/Switches/1/Ports/Up1',
+                          '/redfish/v1/Fabrics/PCIe/Switches/1/Ports/Up2',
+                          '/redfish/v1/Fabrics/PCIe/Switches/1/Ports/Down1',
+                          '/redfish/v1/Fabrics/PCIe/Switches/1/Ports/Down2'),
+                         self.port_col.members_identities)
+
+    @mock.patch.object(port, 'Port', autospec=True)
+    def test_get_member(self, mock_port):
+        self.port_col.get_member(
+            '/redfish/v1/Fabrics/PCIe/Switches/1/Ports/Up1')
+        mock_port.assert_called_once_with(
+            self.port_col._conn,
+            '/redfish/v1/Fabrics/PCIe/Switches/1/Ports/Up1',
+            redfish_version=self.port_col.redfish_version)
+
+    @mock.patch.object(port, 'Port', autospec=True)
+    def test_get_members(self, mock_port):
+        members = self.port_col.get_members()
+        mock_port.assert_called_with(
+            self.port_col._conn, '/redfish/v1/Fabrics/PCIe/Switches/1/'
+                                 'Ports/Down2',
+            redfish_version='1.0.2')
+        self.assertIsInstance(members, list)
+        self.assertEqual(mock_port.call_count, 4)
+        self.assertEqual(4, len(members))
diff --git a/rsd_lib/tests/unit/resources/v2_1/fabric/test_switch.py b/rsd_lib/tests/unit/resources/v2_1/fabric/test_switch.py
index 34d40ba..5458f48 100644
--- a/rsd_lib/tests/unit/resources/v2_1/fabric/test_switch.py
+++ b/rsd_lib/tests/unit/resources/v2_1/fabric/test_switch.py
@@ -14,11 +14,11 @@
 #    under the License.
 
 import json
-
 import mock
-import testtools
 
+from rsd_lib.resources.v2_1.fabric import port
 from rsd_lib.resources.v2_1.fabric import switch
+import testtools
 
 
 class SwitchTestCase(testtools.TestCase):
@@ -53,8 +53,6 @@ class SwitchTestCase(testtools.TestCase):
         self.assertEqual(97, self.switch_inst.total_switch_width)
         self.assertEqual(None, self.switch_inst.indicator_led)
         self.assertEqual('On', self.switch_inst.power_state)
-        self.assertEqual('/redfish/v1/Fabrics/PCIe/Switches/1/Ports',
-                         self.switch_inst.ports.identity)
         self.assertEqual(('/redfish/v1/Chassis/PCIeSwitch1',), self.
                          switch_inst.
                          links.chassis)
@@ -69,6 +67,57 @@ class SwitchTestCase(testtools.TestCase):
             '/redfish/v1/Fabrics/PCIe/Switches/1/Actions/Switch.Reset',
             data={"ResetType": "GracefulRestart"})
 
+    def test__get_ports_path(self):
+        expected = '/redfish/v1/Fabrics/PCIe/Switches/1/Ports'
+        result = self.switch_inst._get_ports_path()
+        self.assertEqual(expected, result)
+
+    def test_ports(self):
+        # | GIVEN |
+        self.conn.get.return_value.json.reset_mock()
+        with open('rsd_lib/tests/unit/json_samples/v2_1/'
+                  'fabrics_port.json', 'r') as f:
+            self.conn.get.return_value.json.return_value = json.loads(f.read())
+        # | WHEN |
+        actual_ports = self.switch_inst.ports
+        # | THEN |
+        self.assertIsInstance(actual_ports,
+                              port.PortCollection)
+        self.conn.get.return_value.json.assert_called_once_with()
+
+        # reset mock
+        self.conn.get.return_value.json.reset_mock()
+        # | WHEN & THEN |
+        # tests for same object on invoking subsequently
+        self.assertIs(actual_ports,
+                      self.switch_inst.ports)
+        self.conn.get.return_value.json.assert_not_called()
+
+    def test_ports_on_refresh(self):
+        # | GIVEN |
+        with open('rsd_lib/tests/unit/json_samples/v2_1/'
+                  'fabrics_port.json', 'r') as f:
+            self.conn.get.return_value.json.return_value = json.loads(f.read())
+        # | WHEN & THEN |
+        self.assertIsInstance(self.switch_inst.ports,
+                              port.PortCollection)
+
+        # On refreshing the manager instance...
+        with open('rsd_lib/tests/unit/json_samples/v2_1/'
+                  'switch.json', 'r') as f:
+            self.conn.get.return_value.json.return_value = json.loads(f.read())
+
+        self.switch_inst.invalidate()
+        self.switch_inst.refresh(force=False)
+
+        # | GIVEN |
+        with open('rsd_lib/tests/unit/json_samples/v2_1/'
+                  'fabrics_port.json', 'r') as f:
+            self.conn.get.return_value.json.return_value = json.loads(f.read())
+        # | WHEN & THEN |
+        self.assertIsInstance(self.switch_inst.ports,
+                              port.PortCollection)
+
 
 class SwitchCollectionTestCase(testtools.TestCase):