diff --git a/examples/lorawan/Makefile b/examples/lorawan/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..35851ede74d208b1c5bda7470b816a4555bd9622
--- /dev/null
+++ b/examples/lorawan/Makefile
@@ -0,0 +1,40 @@
+# name of your application
+APPLICATION = lorawan
+
+# Use the ST B-L072Z-LRWAN1 board by default:
+BOARD ?= b-l072z-lrwan1
+
+# This has to be the absolute path to the RIOT base directory:
+RIOTBASE ?= $(CURDIR)/../..
+
+BOARD_INSUFFICIENT_MEMORY := nucleo32-f031 nucleo32-f042 nucleo32-l031
+
+DEVEUI ?= 0000000000000000
+APPEUI ?= 0000000000000000
+APPKEY ?= 00000000000000000000000000000000
+
+# Default radio driver is Semtech SX1276 (used by the B-L072Z-LRWAN1 board)
+DRIVER ?= sx1276
+
+# Default region is Europe and default band is 868MHz
+REGION ?= EU868
+
+# Include the Semtech-loramac package
+USEPKG += semtech-loramac
+
+USEMODULE += $(DRIVER)
+USEMODULE += fmt
+FEATURES_REQUIRED += periph_rtc
+
+CFLAGS += -DREGION_$(REGION)
+CFLAGS += -DDEVEUI=\"$(DEVEUI)\" -DAPPEUI=\"$(APPEUI)\" -DAPPKEY=\"$(APPKEY)\"
+
+# Comment this out to disable code in RIOT that does safety checking
+# which is not needed in a production environment but helps in the
+# development process:
+DEVELHELP ?= 1
+
+# Change this to 0 show compiler invocation lines by default:
+QUIET ?= 1
+
+include $(RIOTBASE)/Makefile.include
diff --git a/examples/lorawan/README.md b/examples/lorawan/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..934a79ce6e3f2613368a4f212cd77768b6550819
--- /dev/null
+++ b/examples/lorawan/README.md
@@ -0,0 +1,38 @@
+LoRaWAN
+=======
+
+Description
+-----------
+
+This application shows a simple use case of LoRaWAN with RIOT.
+
+By using the real time clock and low-power capabilities of a board, this
+application shows how to program a LoRaWAN Class A devices using RIOT.
+
+This application is using the Over-The-Air Activation procedure.
+
+Usage
+-----
+
+Simply build and flash the application for a ST B-L072Z-LRWAN1 board:
+
+    make flash term
+
+Use the `BOARD`, `DRIVER` and `REGION` make variables to adapt the application
+to your hardware setup and region of use:
+
+- `BOARD` can be one of the nucleo-64 boards
+- `DRIVER` can be either `sx1276` or `sx1272`
+- `REGION` can be `EU868`, `US915`, etc (see LoRaWAN regional parameters for
+  details).
+
+ST Nucleo-64 can be used with an mbed LoRa shield: there's one based on
+[the sx1276 radio](https://os.mbed.com/components/SX1276MB1xAS/) and one based
+on the [the sx1272 radio](https://os.mbed.com/components/SX1272MB2xAS/).
+
+Finally, to join a LoRaWAN network using OTAA activation, edit the application
+`Makefile` and set your device information:
+
+    DEVEUI ?= 0000000000000000
+    APPEUI ?= 0000000000000000
+    APPKEY ?= 00000000000000000000000000000000
diff --git a/examples/lorawan/main.c b/examples/lorawan/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..97770294d03f8634513a28ced684c47166305f46
--- /dev/null
+++ b/examples/lorawan/main.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2018 Inria
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License v2.1. See the file LICENSE in the top level
+ * directory for more details.
+ */
+
+/**
+ * @ingroup     examples
+ * @{
+ *
+ * @file
+ * @brief       Example demonstrating the use of LoRaWAN with RIOT
+ *
+ * @author      Alexandre Abadie <alexandre.abadie@inria.fr>
+ *
+ * @}
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "msg.h"
+#include "thread.h"
+#include "fmt.h"
+
+#include "periph/rtc.h"
+
+#include "net/loramac.h"
+#include "semtech_loramac.h"
+
+/* Messages are sent every 20s to respect the duty cycle on each channel */
+#define PERIOD              (20U)
+
+#define SENDER_PRIO         (THREAD_PRIORITY_MAIN - 1)
+static kernel_pid_t sender_pid;
+static char sender_stack[THREAD_STACKSIZE_MAIN / 2];
+
+semtech_loramac_t loramac;
+
+static const char *message = "This is RIOT!";
+
+static uint8_t deveui[LORAMAC_DEVEUI_LEN];
+static uint8_t appeui[LORAMAC_APPEUI_LEN];
+static uint8_t appkey[LORAMAC_APPKEY_LEN];
+
+static void rtc_cb(void *arg)
+{
+    (void) arg;
+    msg_t msg;
+    msg_send(&msg, sender_pid);
+}
+
+static void _prepare_next_alarm(void)
+{
+    struct tm time;
+    rtc_get_time(&time);
+    /* set initial alarm */
+    time.tm_sec += PERIOD;
+    mktime(&time);
+    rtc_set_alarm(&time, rtc_cb, NULL);
+}
+
+static void _send_message(void)
+{
+    printf("Sending: %s\n", message);
+    /* The send call blocks until done */
+    semtech_loramac_send(&loramac, (uint8_t *)message, strlen(message));
+    /* Wait until the send cycle has completed */
+    semtech_loramac_recv(&loramac);
+}
+
+static void *sender(void *arg)
+{
+    (void)arg;
+
+    msg_t msg;
+    msg_t msg_queue[8];
+    msg_init_queue(msg_queue, 8);
+
+    while (1) {
+        msg_receive(&msg);
+
+        /* Trigger the message send */
+        _send_message();
+
+        /* Schedule the next wake-up alarm */
+        _prepare_next_alarm();
+    }
+
+    /* this should never be reached */
+    return NULL;
+}
+
+int main(void)
+{
+    puts("LoRaWAN Class A low-power application");
+    puts("=====================================");
+
+    /* Convert identifiers and application key */
+    fmt_hex_bytes(deveui, DEVEUI);
+    fmt_hex_bytes(appeui, APPEUI);
+    fmt_hex_bytes(appkey, APPKEY);
+
+    /* Initialize the loramac stack */
+    semtech_loramac_init(&loramac);
+    semtech_loramac_set_deveui(&loramac, deveui);
+    semtech_loramac_set_appeui(&loramac, appeui);
+    semtech_loramac_set_appkey(&loramac, appkey);
+
+    /* Use a fast datarate, e.g. BW125/SF7 in EU868 */
+    semtech_loramac_set_dr(&loramac, LORAMAC_DR_5);
+
+    /* Start the Over-The-Air Activation (OTAA) procedure to retrieve the
+     * generated device address and to get the network and application session
+     * keys.
+     */
+    puts("Starting join procedure");
+    if (semtech_loramac_join(&loramac, LORAMAC_JOIN_OTAA) != SEMTECH_LORAMAC_JOIN_SUCCEEDED) {
+        puts("Join procedure failed");
+        return 1;
+    }
+    puts("Join procedure succeeded");
+
+    /* start the sender thread */
+    sender_pid = thread_create(sender_stack, sizeof(sender_stack),
+                               SENDER_PRIO, 0, sender, NULL, "sender");
+
+    /* trigger the first send */
+    msg_t msg;
+    msg_send(&msg, sender_pid);
+    return 0;
+}