diff --git a/.coveragerc b/.coveragerc
index cd338ddccf0f404c538c9a62b61a37c0755e6d16..0efed20b3304f52a2d0d9132defde520b9d1e569 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -88,6 +88,9 @@ omit =
     homeassistant/components/homematic.py
     homeassistant/components/*/homematic.py
 
+    homeassistant/components/pilight.py
+    homeassistant/components/*/pilight.py
+
     homeassistant/components/knx.py
     homeassistant/components/switch/knx.py
     homeassistant/components/binary_sensor/knx.py
diff --git a/homeassistant/components/pilight.py b/homeassistant/components/pilight.py
new file mode 100644
index 0000000000000000000000000000000000000000..c1b8c1e26e00254adaf00766689957529128e5e4
--- /dev/null
+++ b/homeassistant/components/pilight.py
@@ -0,0 +1,112 @@
+"""
+Component to create an interface to a Pilight daemon (https://pilight.org/).
+
+Pilight can be used to send and receive signals from a radio frequency
+module (RF receiver).
+
+RF commands received by the daemon are put on the HA event bus.
+RF commands can also be send with a pilight.send service call.
+"""
+# pylint: disable=import-error
+import logging
+import socket
+
+import voluptuous as vol
+
+import homeassistant.helpers.config_validation as cv
+from homeassistant.helpers.config_validation import ensure_list
+from homeassistant.const import EVENT_HOMEASSISTANT_START
+from homeassistant.const import EVENT_HOMEASSISTANT_STOP
+from homeassistant.const import CONF_HOST, CONF_PORT
+
+REQUIREMENTS = ['pilight==0.0.2']
+
+DOMAIN = "pilight"
+EVENT = 'pilight_received'
+SERVICE_NAME = 'send'
+
+CONF_WHITELIST = 'whitelist'
+
+CONFIG_SCHEMA = vol.Schema({
+    DOMAIN: vol.Schema({
+        vol.Required(CONF_HOST, default='127.0.0.1'): cv.string,
+        vol.Required(CONF_PORT, default=5000): vol.Coerce(int),
+        vol.Optional(CONF_WHITELIST): {cv.string: [cv.string]}
+    }),
+}, extra=vol.ALLOW_EXTRA)
+
+# The pilight code schema depends on the protocol
+# Thus only require to have the protocol information
+ATTR_PROTOCOL = 'protocol'
+RF_CODE_SCHEMA = vol.Schema({vol.Required(ATTR_PROTOCOL): cv.string},
+                            extra=vol.ALLOW_EXTRA)
+
+_LOGGER = logging.getLogger(__name__)
+
+
+def setup(hass, config):
+    """Setup pilight component."""
+    from pilight import pilight
+
+    try:
+        pilight_client = pilight.Client(host=config[DOMAIN][CONF_HOST],
+                                        port=config[DOMAIN][CONF_PORT])
+    except (socket.error, socket.timeout) as err:
+        _LOGGER.error(
+            "Unable to connect to %s on port %s: %s",
+            config[CONF_HOST], config[CONF_PORT], err)
+        return False
+
+    # Start / stop pilight-daemon connection with HA start/stop
+    def start_pilight_client(_):
+        """Called once when home assistant starts."""
+        pilight_client.start()
+
+    hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_pilight_client)
+
+    def stop_pilight_client(_):
+        """Called once when home assistant stops."""
+        pilight_client.stop()
+
+    hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_pilight_client)
+
+    def send_code(call):
+        """Send RF code to the pilight-daemon."""
+        message_data = call.data
+
+        # Patch data because of bug:
+        # https://github.com/pilight/pilight/issues/296
+        # Protocol has to be in a list otherwise segfault in pilight-daemon
+        message_data["protocol"] = ensure_list(message_data["protocol"])
+
+        try:
+            pilight_client.send_code(message_data)
+        except IOError:
+            _LOGGER.error('Pilight send failed for %s', str(message_data))
+
+    hass.services.register(DOMAIN, SERVICE_NAME,
+                           send_code, schema=RF_CODE_SCHEMA)
+
+    # Publish received codes on the HA event bus
+    # A whitelist of codes to be published in the event bus
+    whitelist = config[DOMAIN].get('whitelist', False)
+
+    def handle_received_code(data):
+        """Called when RF codes are received."""
+        # Unravel dict of dicts to make event_data cut in automation rule
+        # possible
+        data = dict(
+            {'protocol': data['protocol'],
+             'uuid': data['uuid']},
+            **data['message'])
+
+        # No whitelist defined, put data on event bus
+        if not whitelist:
+            hass.bus.fire(EVENT, data)
+        # Check if data matches the defined whitelist
+        elif all(data[key] in whitelist[key] for key in whitelist):
+            hass.bus.fire(EVENT, data)
+
+    pilight_client.set_callback(handle_received_code)
+
+    return True
diff --git a/homeassistant/components/switch/pilight.py b/homeassistant/components/switch/pilight.py
new file mode 100644
index 0000000000000000000000000000000000000000..47e040ddb67507c31e1c2290dce15cf0ca642f8d
--- /dev/null
+++ b/homeassistant/components/switch/pilight.py
@@ -0,0 +1,110 @@
+"""
+Support for switching devices via pilight to on and off.
+
+For more details about this platform, please refer to the documentation at
+https://home-assistant.io/components/switch.pilight/
+"""
+import logging
+
+from homeassistant.helpers.config_validation import ensure_list
+import homeassistant.components.pilight as pilight
+from homeassistant.components.switch import SwitchDevice
+
+DEPENDENCIES = ['pilight']
+
+_LOGGER = logging.getLogger(__name__)
+
+
+def setup_platform(hass, config, add_devices_callback, discovery_info=None):
+    """Setup the pilight platform."""
+    # Find and return switches controlled by pilight
+    switches = config.get('switches', {})
+    devices = []
+
+    for dev_name, properties in switches.items():
+        devices.append(
+            PilightSwitch(
+                hass,
+                properties.get('name', dev_name),
+                properties.get('on_code'),
+                properties.get('off_code'),
+                ensure_list(properties.get('on_code_receive', False)),
+                ensure_list(properties.get('off_code_receive', False))))
+
+    add_devices_callback(devices)
+
+
+class PilightSwitch(SwitchDevice):
+    """Representation of a pilight switch."""
+
+    # pylint: disable=too-many-arguments, too-many-instance-attributes
+    def __init__(self, hass, name, code_on, code_off,
+                 code_on_receive, code_off_receive):
+        """Initialize the switch."""
+        self._hass = hass
+        self._name = name
+        self._state = False
+        self._code_on = code_on
+        self._code_off = code_off
+        self._code_on_receive = code_on_receive
+        self._code_off_receive = code_off_receive
+
+        if any(self._code_on_receive) or any(self._code_off_receive):
+            hass.bus.listen(pilight.EVENT, self._handle_code)
+
+    @property
+    def name(self):
+        """Get the name of the switch."""
+        return self._name
+
+    @property
+    def should_poll(self):
+        """No polling needed, state set when correct code is received."""
+        return False
+
+    @property
+    def is_on(self):
+        """Return true if switch is on."""
+        return self._state
+
+    def _handle_code(self, call):
+        """Check if received code by the pilight-daemon.
+
+        If the code matches the receive on / off codes of this switch
+        the switch state is changed accordingly.
+        """
+        # Check if a on code is defined to turn this switch on
+        if any(self._code_on_receive):
+            for on_code in self._code_on_receive:  # Loop through codes
+                # True if on_code is contained in received code dict, not
+                # all items have to match
+                if on_code.items() <= call.data.items():
+                    self.turn_on()
+                    # Call turn on only once, even when more than one on
+                    # code is received
+                    break
+
+        # Check if a off code is defined to turn this switch off
+        if any(self._code_off_receive):
+            for off_code in self._code_off_receive:  # Loop through codes
+                # True if off_code is contained in received code dict, not
+                # all items have to match
+                if off_code.items() <= call.data.items():
+                    self.turn_off()
+                    # Call turn off only once, even when more than one off
+                    # code is received
+                    break
+
+    def turn_on(self):
+        """Turn the switch on by calling pilight.send service with on code."""
+        self._hass.services.call(pilight.DOMAIN, pilight.SERVICE_NAME,
+                                 self._code_on, blocking=True)
+        self._state = True
+        self.update_ha_state()
+
+    def turn_off(self):
+        """Turn the switch on by calling pilight.send service with off code."""
+        self._hass.services.call(pilight.DOMAIN, pilight.SERVICE_NAME,
+                                 self._code_off, blocking=True)
+        self._state = False
+        self.update_ha_state()
diff --git a/requirements_all.txt b/requirements_all.txt
index ed09ae53c6aac3a7831a7d3b95b0e18039736cd7..58decd00ae74387d92ed5bdfe7d34063bfacc212 100644
--- a/requirements_all.txt
+++ b/requirements_all.txt
@@ -229,6 +229,9 @@ pexpect==4.0.1
 # homeassistant.components.light.hue
 phue==0.8
 
+# homeassistant.components.pilight
+pilight==0.0.2
+
 # homeassistant.components.media_player.plex
 # homeassistant.components.sensor.plex
 plexapi==2.0.2