diff --git a/chromium/build/linux/system.gyp b/chromium/build/linux/system.gyp
index 628357d10e4efc640de107cb6fe4f4b9e35d4d11..2fb38927e86eb563d1d9e79ba4f33a12f312713e 100644
--- a/chromium/build/linux/system.gyp
+++ b/chromium/build/linux/system.gyp
@@ -1042,14 +1042,6 @@
               '<!@(<(pkg-config) --cflags libudev)'
             ],
           },
-          'link_settings': {
-            'ldflags': [
-              '<!@(<(pkg-config) --libs-only-L --libs-only-other libudev)',
-            ],
-            'libraries': [
-              '<!@(<(pkg-config) --libs-only-l libudev)',
-            ],
-          },
         }],
       ],
     },
diff --git a/chromium/content/browser/device_monitor_udev.cc b/chromium/content/browser/device_monitor_udev.cc
index ddfe053eae2348217141ca34084346cc5a3455aa..4f272dfbcffdb4ec94e9ffaa2a59eb337240dfa4 100644
--- a/chromium/content/browser/device_monitor_udev.cc
+++ b/chromium/content/browser/device_monitor_udev.cc
@@ -6,13 +6,12 @@
 
 #include "content/browser/device_monitor_udev.h"
 
-#include <libudev.h>
-
 #include <string>
 
 #include "base/system_monitor/system_monitor.h"
 #include "content/browser/udev_linux.h"
 #include "content/public/browser/browser_thread.h"
+#include "device/udev_linux/udev.h"
 
 namespace {
 
@@ -72,7 +71,7 @@ void DeviceMonitorLinux::OnDevicesChanged(udev_device* device) {
 
   base::SystemMonitor::DeviceType device_type =
       base::SystemMonitor::DEVTYPE_UNKNOWN;
-  std::string subsystem(udev_device_get_subsystem(device));
+  std::string subsystem(libudev.udev_device_get_subsystem(device));
   for (size_t i = 0; i < arraysize(kSubsystemMap); ++i) {
     if (subsystem == kSubsystemMap[i].subsystem) {
       device_type = kSubsystemMap[i].device_type;
diff --git a/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc b/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc
index a211bb67df1444114db0a83b5406b4b977e38cc1..17870c830a286150b0680192cd24ca171366c752 100644
--- a/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc
+++ b/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc
@@ -5,7 +5,6 @@
 #include "content/browser/gamepad/gamepad_platform_data_fetcher_linux.h"
 
 #include <fcntl.h>
-#include <libudev.h>
 #include <linux/joystick.h>
 #include <string.h>
 #include <sys/stat.h>
@@ -20,6 +19,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "content/browser/udev_linux.h"
+#include "device/udev_linux/udev.h"
 
 namespace {
 
@@ -34,10 +34,10 @@ void CloseFileDescriptorIfValid(int fd) {
 }
 
 bool IsGamepad(udev_device* dev, int* index, std::string* path) {
-  if (!udev_device_get_property_value(dev, "ID_INPUT_JOYSTICK"))
+  if (!libudev.udev_device_get_property_value(dev, "ID_INPUT_JOYSTICK"))
     return false;
 
-  const char* node_path = udev_device_get_devnode(dev);
+  const char* node_path = libudev.udev_device_get_devnode(dev);
   if (!node_path)
     return false;
 
@@ -125,7 +125,7 @@ void GamepadPlatformDataFetcherLinux::RefreshDevice(udev_device* dev) {
     // joystick device. In order to get the information about the physical
     // hardware, get the parent device that is also in the "input" subsystem.
     // This function should just walk up the tree one level.
-    dev = udev_device_get_parent_with_subsystem_devtype(
+    dev = libudev.udev_device_get_parent_with_subsystem_devtype(
         dev,
         kInputSubsystem,
         NULL);
@@ -143,34 +143,34 @@ void GamepadPlatformDataFetcherLinux::RefreshDevice(udev_device* dev) {
       return;
     }
 
-    const char* vendor_id = udev_device_get_sysattr_value(dev, "id/vendor");
-    const char* product_id = udev_device_get_sysattr_value(dev, "id/product");
+    const char* vendor_id = libudev.udev_device_get_sysattr_value(dev, "id/vendor");
+    const char* product_id = libudev.udev_device_get_sysattr_value(dev, "id/product");
     mapper = GetGamepadStandardMappingFunction(vendor_id, product_id);
 
     // Driver returns utf-8 strings here, so combine in utf-8 first and
     // convert to WebUChar later once we've picked an id string.
-    const char* name = udev_device_get_sysattr_value(dev, "name");
+    const char* name = libudev.udev_device_get_sysattr_value(dev, "name");
     std::string name_string = base::StringPrintf("%s", name);
 
     // In many cases the information the input subsystem contains isn't
     // as good as the information that the device bus has, walk up further
     // to the subsystem/device type "usb"/"usb_device" and if this device
     // has the same vendor/product id, prefer the description from that.
-    struct udev_device *usb_dev = udev_device_get_parent_with_subsystem_devtype(
+    struct udev_device *usb_dev = libudev.udev_device_get_parent_with_subsystem_devtype(
         dev,
         kUsbSubsystem,
         kUsbDeviceType);
     if (usb_dev) {
       const char* usb_vendor_id =
-          udev_device_get_sysattr_value(usb_dev, "idVendor");
+          libudev.udev_device_get_sysattr_value(usb_dev, "idVendor");
       const char* usb_product_id =
-          udev_device_get_sysattr_value(usb_dev, "idProduct");
+          libudev.udev_device_get_sysattr_value(usb_dev, "idProduct");
 
       if (strcmp(vendor_id, usb_vendor_id) == 0 &&
           strcmp(product_id, usb_product_id) == 0) {
         const char* manufacturer =
-            udev_device_get_sysattr_value(usb_dev, "manufacturer");
-        const char* product = udev_device_get_sysattr_value(usb_dev, "product");
+            libudev.udev_device_get_sysattr_value(usb_dev, "manufacturer");
+        const char* product = libudev.udev_device_get_sysattr_value(usb_dev, "product");
 
         // Replace the previous name string with one containing the better
         // information, again driver returns utf-8 strings here so combine
@@ -207,31 +207,31 @@ void GamepadPlatformDataFetcherLinux::RefreshDevice(udev_device* dev) {
 }
 
 void GamepadPlatformDataFetcherLinux::EnumerateDevices() {
-  udev_enumerate* enumerate = udev_enumerate_new(udev_->udev_handle());
+  udev_enumerate* enumerate = libudev.udev_enumerate_new(udev_->udev_handle());
   if (!enumerate)
     return;
-  int ret = udev_enumerate_add_match_subsystem(enumerate, kInputSubsystem);
+  int ret = libudev.udev_enumerate_add_match_subsystem(enumerate, kInputSubsystem);
   if (ret != 0)
     return;
-  ret = udev_enumerate_scan_devices(enumerate);
+  ret = libudev.udev_enumerate_scan_devices(enumerate);
   if (ret != 0)
     return;
 
-  udev_list_entry* devices = udev_enumerate_get_list_entry(enumerate);
+  udev_list_entry* devices = libudev.udev_enumerate_get_list_entry(enumerate);
   for (udev_list_entry* dev_list_entry = devices;
        dev_list_entry != NULL;
-       dev_list_entry = udev_list_entry_get_next(dev_list_entry)) {
+       dev_list_entry = libudev.udev_list_entry_get_next(dev_list_entry)) {
     // Get the filename of the /sys entry for the device and create a
     // udev_device object (dev) representing it
-    const char* path = udev_list_entry_get_name(dev_list_entry);
-    udev_device* dev = udev_device_new_from_syspath(udev_->udev_handle(), path);
+    const char* path = libudev.udev_list_entry_get_name(dev_list_entry);
+    udev_device* dev = libudev.udev_device_new_from_syspath(udev_->udev_handle(), path);
     if (!dev)
       continue;
     RefreshDevice(dev);
-    udev_device_unref(dev);
+    libudev.udev_device_unref(dev);
   }
   // Free the enumerator object
-  udev_enumerate_unref(enumerate);
+  libudev.udev_enumerate_unref(enumerate);
 }
 
 void GamepadPlatformDataFetcherLinux::ReadDeviceData(size_t index) {
diff --git a/chromium/content/browser/udev_linux.cc b/chromium/content/browser/udev_linux.cc
index f6f9443ab3f66ac82316e77fc01c272b6100547f..106ab16b621b6ea9b86692a83a84b0db4ee7e6dc 100644
--- a/chromium/content/browser/udev_linux.cc
+++ b/chromium/content/browser/udev_linux.cc
@@ -3,8 +3,7 @@
 // found in the LICENSE file.
 
 #include "content/browser/udev_linux.h"
-
-#include <libudev.h>
+#include "device/udev_linux/udev.h"
 
 #include "base/message_loop/message_loop.h"
 
@@ -12,24 +11,24 @@ namespace content {
 
 UdevLinux::UdevLinux(const std::vector<UdevMonitorFilter>& filters,
                      const UdevNotificationCallback& callback)
-    : udev_(udev_new()),
+    : udev_(libudev.udev_new()),
       monitor_(NULL),
       monitor_fd_(-1),
       callback_(callback) {
   CHECK(udev_);
 
-  monitor_ = udev_monitor_new_from_netlink(udev_, "udev");
+  monitor_ = libudev.udev_monitor_new_from_netlink(udev_, "udev");
   CHECK(monitor_);
 
   for (size_t i = 0; i < filters.size(); ++i) {
-    int ret = udev_monitor_filter_add_match_subsystem_devtype(
+    int ret = libudev.udev_monitor_filter_add_match_subsystem_devtype(
         monitor_, filters[i].subsystem, filters[i].devtype);
     CHECK_EQ(0, ret);
   }
 
-  int ret = udev_monitor_enable_receiving(monitor_);
+  int ret = libudev.udev_monitor_enable_receiving(monitor_);
   CHECK_EQ(0, ret);
-  monitor_fd_ = udev_monitor_get_fd(monitor_);
+  monitor_fd_ = libudev.udev_monitor_get_fd(monitor_);
   CHECK_GE(monitor_fd_, 0);
 
   bool success = base::MessageLoopForIO::current()->WatchFileDescriptor(
@@ -43,8 +42,8 @@ UdevLinux::UdevLinux(const std::vector<UdevMonitorFilter>& filters,
 
 UdevLinux::~UdevLinux() {
   monitor_watcher_.StopWatchingFileDescriptor();
-  udev_monitor_unref(monitor_);
-  udev_unref(udev_);
+  libudev.udev_monitor_unref(monitor_);
+  libudev.udev_unref(udev_);
 }
 
 udev* UdevLinux::udev_handle() {
@@ -56,12 +55,12 @@ void UdevLinux::OnFileCanReadWithoutBlocking(int fd) {
   // change state. udev_monitor_receive_device() will return a device object
   // representing the device which changed and what type of change occured.
   DCHECK_EQ(monitor_fd_, fd);
-  udev_device* dev = udev_monitor_receive_device(monitor_);
+  udev_device* dev = libudev.udev_monitor_receive_device(monitor_);
   if (!dev)
     return;
 
   callback_.Run(dev);
-  udev_device_unref(dev);
+  libudev.udev_device_unref(dev);
 }
 
 void UdevLinux::OnFileCanWriteWithoutBlocking(int fd) {
diff --git a/chromium/content/content_browser.gypi b/chromium/content/content_browser.gypi
index 4f13c10ef931f8c79285d6906e4c3745b6a62b29..fdf4397dccc9c7c0c5fe0ec543af81577a815001 100644
--- a/chromium/content/content_browser.gypi
+++ b/chromium/content/content_browser.gypi
@@ -1777,6 +1777,11 @@
         'browser/geolocation/wifi_data_provider_linux.cc',
       ],
     }],
+    ['use_udev==1', {
+        'dependencies': [
+          '../device/udev_linux/udev.gyp:udev_linux',
+        ],
+    }],
     ['enable_browser_cdms==1', {
       'sources': [
         'browser/media/cdm/browser_cdm_manager.cc',
diff --git a/chromium/device/udev_linux/udev.cc b/chromium/device/udev_linux/udev.cc
index e10074b5aa74c54daf77f38ee4262d71f243b0d6..e00fb068f10b7801239a9e842d562dabd78d8186 100644
--- a/chromium/device/udev_linux/udev.cc
+++ b/chromium/device/udev_linux/udev.cc
@@ -6,22 +6,24 @@
 
 #include "device/udev_linux/udev.h"
 
+device::LibUdevWrapper libudev;
+
 namespace device {
 
 void UdevDeleter::operator()(udev* dev) const {
-  udev_unref(dev);
+  libudev.udev_unref(dev);
 }
 
 void UdevEnumerateDeleter::operator()(udev_enumerate* enumerate) const {
-  udev_enumerate_unref(enumerate);
+  libudev.udev_enumerate_unref(enumerate);
 }
 
 void UdevDeviceDeleter::operator()(udev_device* device) const {
-  udev_device_unref(device);
+  libudev.udev_device_unref(device);
 }
 
 void UdevMonitorDeleter::operator()(udev_monitor* monitor) const {
-  udev_monitor_unref(monitor);
+  libudev.udev_monitor_unref(monitor);
 }
 
 }  // namespace device
diff --git a/chromium/device/udev_linux/udev.h b/chromium/device/udev_linux/udev.h
index cffb6723cc40eeec0f0ec424f5e9adaed0c87efb..0c7a2ae1704059964c5ab25704f7e18f7b7e6a62 100644
--- a/chromium/device/udev_linux/udev.h
+++ b/chromium/device/udev_linux/udev.h
@@ -13,6 +13,8 @@
 #error "USE_UDEV not defined"
 #endif
 
+#include <dlfcn.h>
+
 namespace device {
 
 struct UdevDeleter {
@@ -33,6 +35,113 @@ typedef scoped_ptr<udev_enumerate, UdevEnumerateDeleter> ScopedUdevEnumeratePtr;
 typedef scoped_ptr<udev_device, UdevDeviceDeleter> ScopedUdevDevicePtr;
 typedef scoped_ptr<udev_monitor, UdevMonitorDeleter> ScopedUdevMonitorPtr;
 
+
+class LibUdevWrapper {
+public:
+    LibUdevWrapper() : m_libUdev(0), m_loaded(false)
+    {
+        load();
+    }
+
+    virtual ~LibUdevWrapper()
+    {
+        if (m_libUdev)
+            dlclose(m_libUdev);
+    }
+
+private:
+    void* m_libUdev;
+    bool m_loaded;
+    void load()
+    {
+        m_libUdev = dlopen("libudev.so.1", RTLD_NOW);
+        m_loaded = m_libUdev;
+        if (resolveMethods())
+            return;
+        if (!m_libUdev)
+            m_libUdev = dlopen("libudev.so.0", RTLD_NOW);
+        m_loaded = m_libUdev;
+        resolveMethods();
+    }
+
+    void* resolve(const char* name)
+    {
+        void* ptr = dlsym(m_libUdev, name);
+        if (!ptr) {
+            m_loaded = false;
+        }
+        return ptr;
+    }
+
+    bool resolveMethods()
+    {
+        if (!m_loaded)
+            return false;
+        udev_new = (udev* (*)())resolve("udev_new");
+        udev_unref = (void (*)(udev*))resolve("udev_unref");
+        udev_monitor_new_from_netlink = (udev_monitor* (*)(udev*, const char*))resolve("udev_monitor_new_from_netlink");
+        udev_monitor_unref = (void (*)(udev_monitor*))resolve("udev_monitor_unref");
+        udev_monitor_enable_receiving = (int (*)(udev_monitor*))resolve("udev_monitor_enable_receiving");
+        udev_monitor_get_fd = (int (*)(udev_monitor*))resolve("udev_monitor_get_fd");
+        udev_monitor_filter_add_match_subsystem_devtype = (int (*)(udev_monitor*, const char*, const char*))resolve("udev_monitor_filter_add_match_subsystem_devtype");
+        udev_monitor_receive_device = (udev_device* (*)(udev_monitor*))resolve("udev_monitor_receive_device");
+        udev_enumerate_new = (udev_enumerate* (*)(udev*))resolve("udev_enumerate_new");
+        udev_enumerate_unref = (void (*)(udev_enumerate*))resolve("udev_enumerate_unref");
+        udev_enumerate_add_match_subsystem = (int (*)(udev_enumerate*, const char*))resolve("udev_enumerate_add_match_subsystem");
+        udev_enumerate_add_match_property = (int (*)(udev_enumerate*, const char*, const char*))resolve("udev_enumerate_add_match_property");
+        udev_enumerate_scan_devices = (int (*)(udev_enumerate*))resolve("udev_enumerate_scan_devices");
+        udev_enumerate_get_list_entry = (udev_list_entry* (*)(udev_enumerate*))resolve("udev_enumerate_get_list_entry");
+        udev_list_entry_get_next = (udev_list_entry* (*)(udev_list_entry*))resolve("udev_list_entry_get_next");
+        udev_list_entry_get_name = (const char* (*)(udev_list_entry*))resolve("udev_list_entry_get_name");
+        udev_device_new_from_syspath = (udev_device* (*)(udev*, const char*))resolve("udev_device_new_from_syspath");
+        udev_device_unref = (void (*)(udev_device*))resolve("udev_device_unref");
+        udev_device_get_syspath = (const char* (*)(udev_device*))resolve("udev_device_get_syspath");
+        udev_device_get_devnode = (const char* (*)(udev_device*))resolve("udev_device_get_devnode");
+        udev_device_get_property_value = (const char* (*)(udev_device*, const char*))resolve("udev_device_get_property_value");
+        udev_device_get_action = (const char* (*)(udev_device*))resolve("udev_device_get_action");
+        udev_device_get_subsystem = (const char* (*)(udev_device*))resolve("udev_device_get_subsystem");
+        udev_device_get_sysattr_value = (const char* (*)(udev_device*, const char*))resolve("udev_device_get_sysattr_value");
+        udev_device_get_parent_with_subsystem_devtype =
+            (struct udev_device* (*)(struct udev_device*, const char*, const char*))resolve("udev_device_get_parent_with_subsystem_devtype");
+
+        return m_loaded;
+    }
+
+public:
+    struct udev* (*udev_new)();
+    void (*udev_unref)(struct udev*);
+
+    struct udev_monitor* (*udev_monitor_new_from_netlink)(struct udev*, const char *name);
+    void (*udev_monitor_unref)(struct udev_monitor*);
+    int (*udev_monitor_enable_receiving)(struct udev_monitor*);
+    int (*udev_monitor_get_fd)(struct udev_monitor*);
+    int (*udev_monitor_filter_add_match_subsystem_devtype)(struct udev_monitor*, const char *subsystem, const char *devtype);
+    struct udev_device* (*udev_monitor_receive_device)(struct udev_monitor*);
+
+    struct udev_enumerate* (*udev_enumerate_new)(struct udev*);
+    void (*udev_enumerate_unref)(struct udev_enumerate*);
+    int (*udev_enumerate_add_match_subsystem)(struct udev_enumerate*, const char *subsystem);
+    int (*udev_enumerate_add_match_property)(struct udev_enumerate*, const char *property, const char *value);
+    int (*udev_enumerate_scan_devices)(struct udev_enumerate*);
+    struct udev_list_entry* (*udev_enumerate_get_list_entry)(struct udev_enumerate*);
+
+    struct udev_list_entry* (*udev_list_entry_get_next)(struct udev_list_entry*);
+    const char* (*udev_list_entry_get_name)(struct udev_list_entry*);
+
+    struct udev_device* (*udev_device_new_from_syspath)(struct udev *udev, const char *syspath);
+    void (*udev_device_unref)(struct udev_device *udev_device);
+    const char* (*udev_device_get_syspath)(struct udev_device *udev_device);
+    const char* (*udev_device_get_devnode)(struct udev_device *udev_device);
+    const char* (*udev_device_get_property_value)(struct udev_device *udev_device, const char *key);
+    const char* (*udev_device_get_action)(struct udev_device *udev_device);
+    const char* (*udev_device_get_subsystem)(struct udev_device *udev_device);
+    const char* (*udev_device_get_sysattr_value)(struct udev_device *udev_device, const char *sysattr);
+    struct udev_device* (*udev_device_get_parent_with_subsystem_devtype)(struct udev_device *udev_device,
+                                                                  const char *subsystem, const char *devtype);
+};
+
 }  // namespace device
 
+extern device::LibUdevWrapper libudev;
+
 #endif  // DEVICE_UDEV_LINUX_UDEV_H_