diff --git a/src/inet/IPAddress.cpp b/src/inet/IPAddress.cpp
index ce65f7875e811f..c5fabfeb9958fd 100644
--- a/src/inet/IPAddress.cpp
+++ b/src/inet/IPAddress.cpp
@@ -33,7 +33,9 @@
 
 #include <inet/IPAddress.h>
 
+#include <inet/InetError.h>
 #include <lib/core/CHIPEncoding.h>
+#include <lib/support/CodeUtils.h>
 
 #include "arpa-inet-compatibility.h"
 
@@ -127,28 +129,58 @@ ip_addr_t IPAddress::ToLwIPAddr(void) const
     {
 #if INET_CONFIG_ENABLE_IPV4
     case IPAddressType::kIPv4:
-        IP_SET_TYPE_VAL(ret, IPADDR_TYPE_V4);
-        *ip_2_ip4(&ret) = IPAddress::ToIPv4();
+        ip_addr_copy_from_ip4(ret, IPAddress::ToIPv4());
         break;
 #endif // INET_CONFIG_ENABLE_IPV4
 
     case IPAddressType::kIPv6:
-        IP_SET_TYPE_VAL(ret, IPADDR_TYPE_V6);
-        *ip_2_ip6(&ret) = IPAddress::ToIPv6();
+        ip_addr_copy_from_ip6(ret, IPAddress::ToIPv6());
         break;
 
     default:
-#if INET_CONFIG_ENABLE_IPV4
-        ret = *IP_ADDR_ANY;
-#else
         ret = *IP6_ADDR_ANY;
-#endif
         break;
     }
 
     return ret;
 }
 
+CHIP_ERROR IPAddress::ToLwIPAddr(IPAddressType addressType, ip_addr_t & outAddress) const
+{
+    VerifyOrReturnError(addressType != IPAddressType::kUnknown, CHIP_ERROR_INVALID_ARGUMENT);
+
+    switch (Type())
+    {
+#if INET_CONFIG_ENABLE_IPV4
+    case IPAddressType::kIPv4:
+        ip_addr_copy_from_ip4(outAddress, IPAddress::ToIPv4());
+        return (addressType == IPAddressType::kIPv6) ? INET_ERROR_WRONG_ADDRESS_TYPE : CHIP_NO_ERROR;
+#endif // INET_CONFIG_ENABLE_IPV4
+
+    case IPAddressType::kIPv6:
+        ip_addr_copy_from_ip6(outAddress, IPAddress::ToIPv6());
+#if INET_CONFIG_ENABLE_IPV4
+        return (addressType == IPAddressType::kIPv4) ? INET_ERROR_WRONG_ADDRESS_TYPE : CHIP_NO_ERROR;
+#else
+        return CHIP_NO_ERROR;
+#endif // INET_CONFIG_ENABLE_IPV4
+
+    case IPAddressType::kAny:
+#if INET_CONFIG_ENABLE_IPV4
+        if (addressType == IPAddressType::kIPv4)
+        {
+            outAddress = *IP4_ADDR_ANY;
+            return CHIP_NO_ERROR;
+        }
+#endif // INET_CONFIG_ENABLE_IPV4
+        outAddress = *IP6_ADDR_ANY;
+        return CHIP_NO_ERROR;
+
+    default:
+        return INET_ERROR_WRONG_ADDRESS_TYPE;
+    }
+}
+
 lwip_ip_addr_type IPAddress::ToLwIPAddrType(IPAddressType typ)
 {
     lwip_ip_addr_type ret;
diff --git a/src/inet/IPAddress.h b/src/inet/IPAddress.h
index 3b502a8293a1fc..db9f7bb06d255e 100644
--- a/src/inet/IPAddress.h
+++ b/src/inet/IPAddress.h
@@ -33,6 +33,7 @@
 #include <string.h>
 #include <type_traits>
 
+#include <lib/core/CHIPError.h>
 #include <lib/support/BitFlags.h>
 #include <lib/support/DLLUtil.h>
 
@@ -485,6 +486,15 @@ class DLL_EXPORT IPAddress
      */
     ip_addr_t ToLwIPAddr(void) const;
 
+    /**
+     * Extract the IP address as a LwIP ip_addr_t structure.
+     *
+     * If the IP address is Any, the result is IP6_ADDR_ANY unless the requested addressType is kIPv4.
+     * If the requested addressType is IPAddressType::kAny, extracts the IP address as an LwIP ip_addr_t structure.
+     * Otherwise, returns INET_ERROR_WRONG_ADDRESS_TYPE if the requested addressType does not match the IP address.
+     */
+    CHIP_ERROR ToLwIPAddr(IPAddressType addressType, ip_addr_t & outAddress) const;
+
     /**
      * @brief   Convert the INET layer address type to its underlying LwIP type.
      *
diff --git a/src/inet/TCPEndPointImplLwIP.cpp b/src/inet/TCPEndPointImplLwIP.cpp
index 6fb08a8ffd3d1a..cc454552b3fb32 100644
--- a/src/inet/TCPEndPointImplLwIP.cpp
+++ b/src/inet/TCPEndPointImplLwIP.cpp
@@ -67,30 +67,18 @@ CHIP_ERROR TCPEndPointImplLwIP::BindImpl(IPAddressType addrType, const IPAddress
     CHIP_ERROR res = GetPCB(addrType);
 
     // Bind the PCB to the specified address/port.
+    ip_addr_t ipAddr;
     if (res == CHIP_NO_ERROR)
     {
         if (reuseAddr)
         {
             ip_set_option(mTCP, SOF_REUSEADDR);
         }
+        res = addr.ToLwIPAddr(addrType, ipAddr);
+    }
 
-        ip_addr_t ipAddr;
-        if (addr != IPAddress::Any)
-        {
-            ipAddr = addr.ToLwIPAddr();
-        }
-        else if (addrType == IPAddressType::kIPv6)
-        {
-            ipAddr = ip6_addr_any;
-        }
-#if INET_CONFIG_ENABLE_IPV4
-        else if (addrType == IPAddressType::kIPv4)
-        {
-            ipAddr = ip_addr_any;
-        }
-#endif // INET_CONFIG_ENABLE_IPV4
-        else
-            res = INET_ERROR_WRONG_ADDRESS_TYPE;
+    if (res == CHIP_NO_ERROR)
+    {
         res = chip::System::MapErrorLwIP(tcp_bind(mTCP, &ipAddr, port));
     }
 
diff --git a/src/inet/UDPEndPointImplLwIP.cpp b/src/inet/UDPEndPointImplLwIP.cpp
index e5f74911bbd0a1..f21185741ceeaa 100644
--- a/src/inet/UDPEndPointImplLwIP.cpp
+++ b/src/inet/UDPEndPointImplLwIP.cpp
@@ -72,22 +72,14 @@ CHIP_ERROR UDPEndPointImplLwIP::BindImpl(IPAddressType addressType, const IPAddr
     CHIP_ERROR res = GetPCB(addressType);
 
     // Bind the PCB to the specified address/port.
+    ip_addr_t ipAddr;
     if (res == CHIP_NO_ERROR)
     {
-        ip_addr_t ipAddr = address.ToLwIPAddr();
-
-        // TODO: IPAddress ANY has only one constant state, however addressType
-        // has separate IPV4 and IPV6 'any' settings. This tries to correct
-        // for this as LWIP default if IPv4 is compiled in is to consider
-        // 'any == any_v4'
-        //
-        // We may want to consider having separate AnyV4 and AnyV6 constants
-        // inside CHIP to resolve this ambiguity
-        if ((address.Type() == IPAddressType::kAny) && (addressType == IPAddressType::kIPv6))
-        {
-            ipAddr = *IP6_ADDR_ANY;
-        }
+        res = address.ToLwIPAddr(addressType, ipAddr);
+    }
 
+    if (res == CHIP_NO_ERROR)
+    {
         res = chip::System::MapErrorLwIP(udp_bind(mUDP, &ipAddr, port));
     }
 
diff --git a/src/inet/tests/TestInetAddress.cpp b/src/inet/tests/TestInetAddress.cpp
index f29ca49e2b5327..0710a57e39e12d 100644
--- a/src/inet/tests/TestInetAddress.cpp
+++ b/src/inet/tests/TestInetAddress.cpp
@@ -44,6 +44,7 @@
 #include <nlunit-test.h>
 
 #include <inet/IPPrefix.h>
+#include <inet/InetError.h>
 
 #include <lib/support/CodeUtils.h>
 #include <lib/support/UnitTestRegistration.h>
@@ -1710,6 +1711,109 @@ void CheckIPPrefix(nlTestSuite * inSuite, void * inContext)
     }
 }
 
+#if CHIP_SYSTEM_CONFIG_USE_LWIP
+
+bool sameLwIPAddress(const ip6_addr_t & a, const ip6_addr_t & b)
+{
+    return (a.addr[0] == b.addr[0]) && (a.addr[1] == b.addr[1]) && (a.addr[2] == b.addr[2]) && (a.addr[3] == b.addr[3]);
+}
+
+#if LWIP_IPV4 && LWIP_IPV6
+bool sameLwIPAddress(const ip_addr_t & a, const ip_addr_t & b)
+{
+    switch (a.type)
+    {
+    case IPADDR_TYPE_V4:
+        return (b.type == IPADDR_TYPE_V4) && (a.u_addr.ip4.addr == b.u_addr.ip4.addr);
+    case IPADDR_TYPE_V6:
+        return (b.type == IPADDR_TYPE_V6) && sameLwIPAddress(a.u_addr.ip6, b.u_addr.ip6);
+    default:
+        return false;
+    }
+}
+#endif // LWIP_IPV4 && LWIP_IPV6
+
+/**
+ * Test ToLwIPAddress()
+ */
+void CheckToLwIPAddr(nlTestSuite * inSuite, void * inContext)
+{
+    const struct TestContext * lContext       = static_cast<const struct TestContext *>(inContext);
+    IPAddressExpandedContextIterator lCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
+    IPAddressExpandedContextIterator lEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
+    CHIP_ERROR err;
+    ip_addr_t lwip_expected_addr, lwip_check_addr;
+
+    while (lCurrent != lEnd)
+    {
+        IPAddress test_addr;
+
+        SetupIPAddress(test_addr, lCurrent);
+
+#if INET_CONFIG_ENABLE_IPV4
+        if (lCurrent->mAddr.mAddrType == IPAddressType::kIPv4)
+        {
+            ip_addr_copy_from_ip4(lwip_expected_addr, test_addr.ToIPv4());
+            lwip_check_addr = test_addr.ToLwIPAddr();
+            NL_TEST_ASSERT(inSuite, sameLwIPAddress(lwip_expected_addr, lwip_check_addr));
+
+            err = test_addr.ToLwIPAddr(IPAddressType::kAny, lwip_check_addr);
+            NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+            NL_TEST_ASSERT(inSuite, sameLwIPAddress(lwip_expected_addr, lwip_check_addr));
+
+            err = test_addr.ToLwIPAddr(IPAddressType::kIPv4, lwip_check_addr);
+            NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+            NL_TEST_ASSERT(inSuite, sameLwIPAddress(lwip_expected_addr, lwip_check_addr));
+
+            err = test_addr.ToLwIPAddr(IPAddressType::kIPv6, lwip_check_addr);
+            NL_TEST_ASSERT(inSuite, err == INET_ERROR_WRONG_ADDRESS_TYPE);
+        }
+        else
+#endif // INET_CONFIG_ENABLE_IPV4
+            if (lCurrent->mAddr.mAddrType == IPAddressType::kIPv6)
+        {
+            ip_addr_copy_from_ip6(lwip_expected_addr, test_addr.ToIPv6());
+            lwip_check_addr = test_addr.ToLwIPAddr();
+            NL_TEST_ASSERT(inSuite, sameLwIPAddress(lwip_expected_addr, lwip_check_addr));
+
+            err = test_addr.ToLwIPAddr(IPAddressType::kAny, lwip_check_addr);
+            NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+            NL_TEST_ASSERT(inSuite, sameLwIPAddress(lwip_expected_addr, lwip_check_addr));
+
+            err = test_addr.ToLwIPAddr(IPAddressType::kIPv6, lwip_check_addr);
+            NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+            NL_TEST_ASSERT(inSuite, sameLwIPAddress(lwip_expected_addr, lwip_check_addr));
+
+#if INET_CONFIG_ENABLE_IPV4
+            err = test_addr.ToLwIPAddr(IPAddressType::kIPv4, lwip_check_addr);
+            NL_TEST_ASSERT(inSuite, err == INET_ERROR_WRONG_ADDRESS_TYPE);
+#endif // INET_CONFIG_ENABLE_IPV4
+        }
+        else if (lCurrent->mAddr.mAddrType == IPAddressType::kAny)
+        {
+            lwip_check_addr = test_addr.ToLwIPAddr();
+            NL_TEST_ASSERT(inSuite, sameLwIPAddress(*IP6_ADDR_ANY, lwip_check_addr));
+
+            err = test_addr.ToLwIPAddr(IPAddressType::kAny, lwip_check_addr);
+            NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+            NL_TEST_ASSERT(inSuite, sameLwIPAddress(*IP6_ADDR_ANY, lwip_check_addr));
+
+            err = test_addr.ToLwIPAddr(IPAddressType::kIPv6, lwip_check_addr);
+            NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+            NL_TEST_ASSERT(inSuite, sameLwIPAddress(*IP6_ADDR_ANY, lwip_check_addr));
+
+#if INET_CONFIG_ENABLE_IPV4
+            err = test_addr.ToLwIPAddr(IPAddressType::kIPv4, lwip_check_addr);
+            NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+            NL_TEST_ASSERT(inSuite, sameLwIPAddress(*IP4_ADDR_ANY, lwip_check_addr));
+#endif // INET_CONFIG_ENABLE_IPV4
+        }
+
+        ++lCurrent;
+    }
+}
+#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
+
 /**
  *   Test Suite. It lists all the test functions.
  */
@@ -1750,6 +1854,9 @@ const nlTest sTests[] =
     NL_TEST_DEF("Assemble IPv6 Transient Multicast address",   CheckMakeIPv6TransientMulticast),
     NL_TEST_DEF("Assemble IPv6 Prefix Multicast address",      CheckMakeIPv6PrefixMulticast),
     NL_TEST_DEF("IPPrefix test",                               CheckIPPrefix),
+#if CHIP_SYSTEM_CONFIG_USE_LWIP
+    NL_TEST_DEF("Convert IPAddress to LwIP address",           CheckToLwIPAddr),
+#endif
     NL_TEST_SENTINEL()
 };
 // clang-format on